Designing a Rails CMS


#1

Hi, I’m designing a simple CMS, and hope to share the code.

Objectives of CMS:

  • Simple scaffold backend with password protection
  • View a page either by specifying the id or title
  • View a list of pages
    • View latest 5 pages in a section
    • View all pages in last month
    • View all pages in a section paginated
  • URL looks like static site, /folder/page
  • Homepage displayed if no page specified
  • Same template for all pages
  • Handle page not found

So my idea is:

Authors (has_many) Pages (belongs_to) Section

Page

index
view
view_by_id
view_by_title
view_all_in_section
view_latest_in_section

The actions that return one page (@page) will share a view and the
actions that return more than one page (@pages) will share a view.

Now this is where my questions come in:

  1. Do the action names looks good, any better suggestions?
  2. Can I use routes to prevent my action names showing in the URL eg.
    domain.com/page/view_by_id/3” or
    domain.com/page/view_all_in_section/5

Instead I want these URLs:

domain.com/section/page
domain.com/page
domain.com/section/archive
domain.com/section/latest

Something doesn’t quite seem right, because I want my URL to include the
section, but the actions dont need the section as input, only the page
id or title.

Do I need to re-think, should I always include the section, and if no
section is given then use section_id = 1 (root section).

Does the structure of my controller / actions / URL’s seem correct?


#2

krisleech wrote:

Hi, I’m designing a simple CMS, and hope to share the code.

Objectives of CMS:

  • Simple scaffold backend with password protection
  • View a page either by specifying the id or title
  • View a list of pages
    • View latest 5 pages in a section
    • View all pages in last month
    • View all pages in a section paginated
  • URL looks like static site, /folder/page
  • Homepage displayed if no page specified
  • Same template for all pages
  • Handle page not found

So my idea is:

Authors (has_many) Pages (belongs_to) Section

Page

index
view
view_by_id
view_by_title
view_all_in_section
view_latest_in_section

The actions that return one page (@page) will share a view and the
actions that return more than one page (@pages) will share a view.

Now this is where my questions come in:

  1. Do the action names looks good, any better suggestions?
  2. Can I use routes to prevent my action names showing in the URL eg.
    domain.com/page/view_by_id/3” or
    domain.com/page/view_all_in_section/5

Instead I want these URLs:

domain.com/section/page
domain.com/page
domain.com/section/archive
domain.com/section/latest

Something doesn’t quite seem right, because I want my URL to include the
section, but the actions dont need the section as input, only the page
id or title.

Do I need to re-think, should I always include the section, and if no
section is given then use section_id = 1 (root section).

Does the structure of my controller / actions / URL’s seem correct?

You could use something like this :

map.connect ‘:section/:page’, :controller => ‘page’, :action => ‘show’
map.connect ‘:page’, :controller => ‘page’, :action => ‘show’
map.connect ‘:section/archive’, :controller => ‘page’, :action =>
‘archive’
map.connect ‘:section/latest’, :controller => ‘page’, :action =>
‘latest’
map.connect ‘:controller/:action/:id’

You can even use routes.rb to check if a param i s a number or not and
then send to a different action depending on the result.
Ex /page/78 send to action show_by_id
/page/about send to action show_by_title
Have a look in the agile book. There is a good example in there.

I use the method here under to create an uniq_title_id (based on the
page title) that is url compatible for each of my pages in my page model
in a before_create filter (this app is in french)
ex (in french) : Page about “ruby on rails” will have a uniq_txt_id :
page_about_ruby_on_rails

def create_uniq_txt_id
foo = self.title.downcase.strip
foo.gsub!(/[Ã?ÁÃ?Ã?âäà ãáäåāÄ?Ä?Ç?Ç?ǡǻȁÈ?ȧẵặ]/,‘a’)
foo.gsub!(/[ëêéèẽÄ?Ä?Ä?ẻÈ?È?ẹȩÄ?á¸?á¸?ềếá»?á»?á¸?á¸?á»?ḝ]/,‘e’)
foo.gsub!(/[Ã?ÍÃ?ĨÏiìíîĩīĭïá»?ǐá»?įÈ?È?ḭɨḯ]/,‘i’)
foo.gsub!(/[Ã?Ã?Ã?Ã?Ã?òóôõōŏȯöỏÅ?Ç?ȍȏơǫọɵøá»?á»?á»?á»?ȱȫȭṍṏá¹?á¹?ờá»?ỡá»?ợǭá»?Ç¿]/,‘o’)
foo.gsub!(/[Ã?Ã?Ã?ŨÃ?ùúûũūŭüủůűÇ?È?È?ưụṳųṷṵṹṻÇ?Ç?Ç?Ç?Ç?ừứữửự]/,‘u’)
foo.gsub!(/[ỳýŷỹȳẏÿỷáº?ƴỵ]/,‘y’)
foo.gsub!(/[Å?]/,‘oe’)
foo.gsub!(/[Ã?ǼǢæ]/,‘ae’)
foo.gsub!(/[ñǹÅ?]/,‘n’)
foo.gsub!(/[Ã?ç]/,‘c’)
foo.gsub!(/[Ã?]/,‘b’)
foo.gsub!(/[Å?]/,‘oe’)
foo.gsub!(/[ij]/,‘ij’)
foo.gsub!(/[\s’"\/?.=+&%]/,’’)
foo.gsub!(/
+/,’’)
# test if exist
bar = Scoop.find_by_uniq_txt_id(foo)
foo = foo + '
’ + self.user.login unless bar.nil?

self.uniq_txt_id = foo

end


#3

Hi jm

jm wrote:

foo.gsub!(/[ëêéèẽÄ?Ä?Ä?ẻÈ?È?ẹȩÄ?á¸?á¸?ềếá»?á»?á¸?á¸?á»?ḝ]/,'e')
foo.gsub!(/[ij]/,'ij')
foo.gsub!(/[\s\'\"\\\/\?\.\=\+\&\%]/,'_')
foo.gsub!(/_+/,'_')
# test if exist
bar = Scoop.find_by_uniq_txt_id(foo)
foo = foo + '_' + self.user.login unless bar.nil?

self.uniq_txt_id = foo

end

Thanks for this method. I have always been to lazy to code up something
like this (collecting all those variations of letters). REALLY useful.
Thanks!

Sascha E.


#4

On 23.11.2005, at 17.48, jm removed_email_address@domain.invalid wrote:

You know it is not complete but ok for french, spanish and english
language.
For nordic language, not sure it will work.

Looks fine to me. Nordic languages generally only have å, ä and ö
(+their variations) besides normal ascii. This doesn’t apply to
Icelandish, tho, they have quite a lot of different acutes etc.

Which reminds me… Shouldn’t this be ‘ss’ instead of ‘b’ (assuming
it’s the German double s):

foo.gsub!(/[Ã?]/,‘b’)

//jarkko


#5

On 23-nov-2005, at 11:22, Kris L. wrote:

Hi, I’m designing a simple CMS, and hope to share the code.

Does the structure of my controller / actions / URL’s seem correct?

Have you looked at MuraveyWeb?


#6

se wrote:

Hi jm

jm wrote:

foo.gsub!(/[ëêéèẽÄ?Ä?Ä?ẻÈ?È?ẹȩÄ?á¸?á¸?ềếá»?á»?á¸?á¸?á»?ḝ]/,'e')
foo.gsub!(/[ij]/,'ij')
foo.gsub!(/[\s\'\"\\\/\?\.\=\+\&\%]/,'_')
foo.gsub!(/_+/,'_')
# test if exist
bar = Scoop.find_by_uniq_txt_id(foo)
foo = foo + '_' + self.user.login unless bar.nil?

self.uniq_txt_id = foo

end

Thanks for this method. I have always been to lazy to code up something
like this (collecting all those variations of letters). REALLY useful.
Thanks!

Sascha E.

You know it is not complete but ok for french, spanish and english
language.
For nordic language, not sure it will work.


#7

I have it, but its a bit too much for me at the moment, im looking a lot
simpler.
But on that note I’m thinking since every page served will include a
refrence to the section the page is in I should have a section
controller and not a page controller.

The Section controller would have the following actions:
view_all_pages
view_page
view_latest_pages

And I would have the following URL’s / routing / code:

domain.com/section/

map.connect ‘:section’, :controller => ‘section’, :action =>
‘view_all_pages’

def view_all_pages
@section = Section.find_by_name(params[:section])
@pages << @section.pages
end

domain.com/section/page

map.connect ‘:section/:page’, :controller => ‘section’, :action =>
‘view_page’

def view_page
params[:section] ||= 1
@section = Section.find_by_name(params[:section])
@page << @section.page.view_by_title(params[:page])
end

domain.com/page

map.connect ‘:page’, :controller => ‘section’, :action => ‘view_page’

domain.com/section/archive

map.connect ‘:section/archive’, :controller => ‘section’, :action =>
‘view_all_pages’

domain.com/section/latest

map.connect ‘:section/latest’, :controller => ‘section’, :action =>
‘view_latest’

def view_latest_pages
@section = Section.find_by_name(params[:section])
@page << @section.pages.view_latest
end

Possible flash messages: page not found, section not found, no pages in
this section