merrycms 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/README +15 -0
  2. data/app/controllers/admin/base_controller.rb +11 -0
  3. data/app/controllers/admin/categories_controller.rb +63 -0
  4. data/app/controllers/admin/pages_controller.rb +73 -0
  5. data/app/controllers/admin/translations_controller.rb +55 -0
  6. data/app/controllers/admin/users_controller.rb +53 -0
  7. data/app/helpers/admin/categories_helper.rb +32 -0
  8. data/app/helpers/admin/pages_helper.rb +24 -0
  9. data/app/helpers/admin/translations_helper.rb +25 -0
  10. data/app/helpers/admin/users_helper.rb +10 -0
  11. data/app/models/category.rb +11 -0
  12. data/app/models/page.rb +66 -0
  13. data/app/models/role.rb +6 -0
  14. data/app/models/translation.rb +48 -0
  15. data/app/models/user.rb +42 -0
  16. data/app/views/admin/_nav.html.erb +10 -0
  17. data/app/views/admin/categories/_form.erb +24 -0
  18. data/app/views/admin/categories/edit.html.erb +3 -0
  19. data/app/views/admin/categories/index.html.erb +22 -0
  20. data/app/views/admin/categories/new.html.erb +3 -0
  21. data/app/views/admin/categories/sort.html.erb +29 -0
  22. data/app/views/admin/pages/_form.html.erb +25 -0
  23. data/app/views/admin/pages/_search.erb +15 -0
  24. data/app/views/admin/pages/edit.html.erb +3 -0
  25. data/app/views/admin/pages/index.html.erb +32 -0
  26. data/app/views/admin/pages/new.html.erb +3 -0
  27. data/app/views/admin/translations/_filter.html.erb +8 -0
  28. data/app/views/admin/translations/destroy.js +4 -0
  29. data/app/views/admin/translations/index.html.erb +40 -0
  30. data/app/views/admin/translations/new.html.erb +49 -0
  31. data/app/views/admin/users/_form.html.erb +33 -0
  32. data/app/views/admin/users/edit.html.erb +3 -0
  33. data/app/views/admin/users/index.html.erb +18 -0
  34. data/app/views/admin/users/new.html.erb +3 -0
  35. data/app/views/devise/confirmations/new.html.erb +10 -0
  36. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  37. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  38. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  39. data/app/views/devise/passwords/edit.html.erb +15 -0
  40. data/app/views/devise/passwords/new.html.erb +16 -0
  41. data/app/views/devise/registrations/edit.html.erb +24 -0
  42. data/app/views/devise/registrations/new.html.erb +31 -0
  43. data/app/views/devise/sessions/new.html.erb +24 -0
  44. data/app/views/devise/shared/_links.erb +19 -0
  45. data/app/views/devise/unlocks/new.html.erb +11 -0
  46. data/app/views/layouts/admin.html.erb +22 -0
  47. data/app/views/layouts/login.html.erb +17 -0
  48. data/app/views/shared/_error_messages.html.erb +9 -0
  49. data/app/views/shared/_flashbox.html.erb +5 -0
  50. data/app/views/shared/_toplinks.html.erb +8 -0
  51. data/config/locales/en/admin/missing.yml +4 -0
  52. data/config/locales/fr/admin/admin.fr.yml +9 -0
  53. data/config/locales/fr/admin/category.fr.yml +22 -0
  54. data/config/locales/fr/admin/devise.fr.yml +129 -0
  55. data/config/locales/fr/admin/merrycms.fr.yml +6 -0
  56. data/config/locales/fr/admin/missing.yml +5 -0
  57. data/config/locales/fr/admin/pages.fr.yml +51 -0
  58. data/config/locales/fr/admin/pagination.fr.yml +6 -0
  59. data/config/locales/fr/admin/toplinks.fr.yml +9 -0
  60. data/config/locales/fr/admin/translations.fr.yml +46 -0
  61. data/config/locales/fr/admin/users.fr.yml +14 -0
  62. data/lib/generators/merrycms/install_generator.rb +78 -0
  63. data/lib/generators/merrycms/templates/create_pages_and_categories_migration.rb +36 -0
  64. data/lib/generators/merrycms/templates/create_roles_migration.rb +14 -0
  65. data/lib/generators/merrycms/templates/create_translations_migration.rb +17 -0
  66. data/lib/generators/merrycms/templates/devise_create_users_migration.rb +26 -0
  67. data/lib/generators/merrycms/templates/devise_initializer.rb +142 -0
  68. data/lib/generators/merrycms/templates/locale_initializer.rb +10 -0
  69. data/lib/generators/merrycms/templates/roles_users_migration.rb +13 -0
  70. data/lib/generators/merrycms/views_generator.rb +11 -0
  71. data/lib/merrycms/engine.rb +38 -0
  72. data/lib/merrycms/rails/routes.rb +35 -0
  73. data/lib/merrycms/railties/merrycms_tasks.rake +72 -0
  74. data/lib/merrycms.rb +1 -0
  75. metadata +270 -0
data/README ADDED
@@ -0,0 +1,15 @@
1
+ Install
2
+ gem 'merrycms'
3
+
4
+ $ bundle install
5
+
6
+ Usage
7
+ r g merrycms:install
8
+ rake db:migrate
9
+ rake merrycms:bootstrap
10
+
11
+ start the server
12
+ go to '/admin'
13
+
14
+ How to add a new resource in the admin panel
15
+
@@ -0,0 +1,11 @@
1
+ module Admin
2
+ class BaseController < ApplicationController
3
+
4
+ rescue_from Acl9::AccessDenied, :with => :access_denied
5
+
6
+ def access_denied
7
+ redirect_to admin_root_path, :alert => t('access_denied')
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,63 @@
1
+ module Admin
2
+ class CategoriesController < ApplicationController
3
+
4
+ layout "admin"
5
+
6
+ before_filter :authenticate_user!
7
+ access_control do
8
+ allow :admin
9
+ end
10
+
11
+ def index
12
+ @categories = Category.arrange
13
+ end
14
+
15
+ def new
16
+ @category = Category.new
17
+ end
18
+
19
+ def create
20
+ @category = Category.new(params[:category])
21
+ if @category.save
22
+ redirect_to admin_categories_path
23
+ else
24
+ render :new
25
+ end
26
+ end
27
+
28
+ def edit
29
+ @category = Category.find(params[:id])
30
+ end
31
+
32
+ def update
33
+ @category = Category.find(params[:id])
34
+ if @category.update_attributes(params[:category])
35
+ redirect_to admin_categories_path
36
+ else
37
+ render :edit
38
+ end
39
+ end
40
+
41
+ def destroy
42
+ @category = Category.find(params[:id])
43
+ @category.destroy
44
+ redirect_to admin_categories_path
45
+ end
46
+
47
+ def sort
48
+ @category = Category.find(params[:id])
49
+ @categories = @category.children_by_position
50
+ end
51
+
52
+ def sorting
53
+ categories = Category.find(params[:category])
54
+ categories.each do |category|
55
+ category.position = params[:category].index(category.id.to_s)+1
56
+ category.save
57
+ end
58
+
59
+ render :nothing => true
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,73 @@
1
+ module Admin
2
+ class PagesController < BaseController
3
+
4
+ layout "admin"
5
+
6
+ before_filter :authenticate_user!
7
+ access_control do
8
+ allow :admin
9
+ end
10
+
11
+ def index
12
+ @search = Page.search(params[:search])
13
+ @pages = @search.order(:title).page(params[:page]).per(5)
14
+ end
15
+
16
+ def new
17
+ @page = Page.new
18
+ end
19
+
20
+ def create
21
+ @page = Page.new(params[:page])
22
+ if @page.save
23
+ redirect_to admin_pages_path
24
+ else
25
+ render :new
26
+ end
27
+ end
28
+
29
+ def edit
30
+ @page = Page.find(params[:id])
31
+ end
32
+
33
+ def update
34
+ @page = Page.find(params[:id])
35
+ if @page.update_attributes(params[:page])
36
+ redirect_to admin_pages_path
37
+ else
38
+ render :edit
39
+ end
40
+ end
41
+
42
+ def destroy
43
+ page = Page.find(params[:id])
44
+ page.destroy
45
+ redirect_to admin_pages_path
46
+ end
47
+
48
+ def publish
49
+ page = Page.find(params[:id])
50
+ page.publish!
51
+ redirect_to admin_pages_path
52
+ end
53
+
54
+ def unpublish
55
+ page = Page.find(params[:id])
56
+ page.unpublish!
57
+ redirect_to admin_pages_path
58
+ end
59
+
60
+ def archive
61
+ page = Page.find(params[:id])
62
+ page.archive!
63
+ redirect_to admin_pages_path
64
+ end
65
+
66
+ def unarchive
67
+ page = Page.find(params[:id])
68
+ page.unarchive!
69
+ redirect_to admin_pages_path
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,55 @@
1
+ module Admin
2
+ class TranslationsController < ApplicationController
3
+ respond_to :html, :json
4
+
5
+ layout "admin"
6
+
7
+ before_filter :authenticate_user!
8
+ access_control do
9
+ allow :admin
10
+ end
11
+
12
+ def index
13
+ @pending_translations = Translation.pending.group_by{|t| t.locale }
14
+ @all_translations = Translation.not_pending.group_by{|t| t.locale }
15
+ end
16
+
17
+ def new
18
+ if params[:type] && params[:type] == "pending"
19
+ @translations = Translation.search_query(params[:query]).pending.where(:locale => params[:language]).page(params[:page]).per(10)
20
+ else
21
+ @translations = Translation.search_query(params[:query]).not_pending.where(:locale => params[:language]).page(params[:page]).per(10)
22
+ end
23
+ end
24
+
25
+ def create
26
+ params[:translations].values.each do |record|
27
+ logger.debug("DESTROY : #{record[:destroy]}")
28
+ destroy_record = record.delete(:destroy)
29
+ if destroy_record == "false"
30
+ record_id = record.delete(:id)
31
+ translation = Translation.find(record_id)
32
+ logger.debug("TRANSLATION : #{translation.inspect}")
33
+ logger.debug("RECORD : #{record.inspect}")
34
+ translation.update_attributes(record)
35
+ end
36
+ end
37
+ redirect_to admin_translations_path, :notice => t('translations.notice.translation_added')
38
+ end
39
+
40
+ def destroy
41
+ @translation = Translation.find(params[:id])
42
+ @translation.destroy
43
+ respond_with(@translation) do |format|
44
+ format.html { redirect_to new_admin_translation_path(:type => params[:type], :language => params[:language]) }
45
+ format.js
46
+ end
47
+ end
48
+
49
+ def dump
50
+ Translation.dump_all
51
+ redirect_to admin_translations_path, :notice => t('translations.notice.dumped')
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,53 @@
1
+ module Admin
2
+ class UsersController < BaseController
3
+
4
+ layout "admin"
5
+
6
+ before_filter :authenticate_user!
7
+ access_control do
8
+ allow :admin
9
+ end
10
+
11
+ def index
12
+ @users = User.order(:email).page(params[:page])
13
+ end
14
+
15
+ def new
16
+ @user = User.new
17
+ end
18
+
19
+ def create
20
+ @user = User.new(params[:user])
21
+
22
+ @user.set_roles(params[:roles])
23
+
24
+ if @user.save
25
+ redirect_to admin_users_path
26
+ else
27
+ render :new
28
+ end
29
+ end
30
+
31
+ def edit
32
+ @user = User.find(params[:id])
33
+ end
34
+
35
+ def update
36
+ @user = User.find(params[:id])
37
+ @user.set_roles(params[:roles])
38
+
39
+ if @user.update_attributes(params[:user])
40
+ redirect_to admin_users_path
41
+ else
42
+ render :edit
43
+ end
44
+ end
45
+
46
+ def destroy
47
+ @user = User.find(params[:id])
48
+ @user.destroy
49
+ redirect_to admin_users_path
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,32 @@
1
+ module Admin
2
+ module CategoriesHelper
3
+
4
+ def render_cat hash, options = {}, &block
5
+ sort_proc = options.delete :sort
6
+ content_tag :tr, options do
7
+ content_tag :td do
8
+ hash.keys.sort_by(&sort_proc).each do |node|
9
+ block.call node, render_tree(hash[node], :sort => sort_proc, &block)
10
+ end
11
+ end
12
+ end if hash.present?
13
+ end
14
+
15
+ def display_node(node)
16
+ html = ""
17
+ if node.level
18
+ html << "-" * node.level
19
+ end
20
+ html << " #{node.name}"
21
+ end
22
+
23
+ def display_sort_category_link(node)
24
+ link_to(t('categories.links.sort'), sort_admin_category_path(node)) if node.children.size > 1
25
+ end
26
+
27
+ def display_edit_category_link(node)
28
+ link_to(t('categories.links.edit'), edit_admin_category_path(node)) unless node.name == 'root'
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ module Admin
2
+ module PagesHelper
3
+
4
+ def display_page_category(page)
5
+ if page.category
6
+ page.category.name
7
+ end
8
+ end
9
+
10
+ def display_state(page)
11
+ t("pages.states.#{page.state}")
12
+ end
13
+
14
+ def display_events(page)
15
+ html = ""
16
+ page.available_events.each do |event|
17
+ html << link_to(t("pages.events.#{event}"), method("#{event}_admin_page_path").call(page))
18
+ html << '&nbsp;'
19
+ end
20
+ raw(html)
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ module Admin
2
+ module TranslationsHelper
3
+
4
+ def display_available_locales
5
+ I18n.available_locales.map{|locale| t("translations.locales.#{locale}") }.join(", ")
6
+ end
7
+
8
+ def display_translation_if_exist(translation)
9
+ other_locales = I18n.available_locales - [translation[:locale].to_sym]
10
+ other_locale = other_locales.first
11
+ if other_locale
12
+ other_translation = Translation.find_by_key_and_locale(translation[:key], other_locale)
13
+ if other_translation
14
+ html = "<p>#{other_translation.value}</p>"
15
+ else
16
+ html = "<p class='no_translation'>#{t('translations.no_translation')}</p>"
17
+ end
18
+ else
19
+ html = "<p class='no_translation'>#{t('translations.no_translation')}</p>"
20
+ end
21
+ raw html
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,10 @@
1
+ module Admin
2
+ module UsersHelper
3
+
4
+ def display_user_roles(user)
5
+ logger.debug("ROLES : #{user.role_list}")
6
+ user.role_list.map{|r| r.name if r }.join(', ')
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ class Category < ActiveRecord::Base
2
+ acts_as_nested_set
3
+ has_friendly_id :name, :use_slug => true, :cache_column => 'link',:approximate_ascii => true, :ascii_approximation_options => :german
4
+
5
+ has_many :pages
6
+
7
+ def children_by_position
8
+ Category.scoped :conditions => { parent_column_name => self }, :order => "position"
9
+ end
10
+
11
+ end
@@ -0,0 +1,66 @@
1
+ require 'active_record/transitions'
2
+
3
+ class Page < ActiveRecord::Base
4
+ include ActiveRecord::Transitions
5
+
6
+ belongs_to :category
7
+
8
+ validates_presence_of :title
9
+ has_friendly_id :title, :use_slug => true, :cache_column => 'link',:approximate_ascii => true, :ascii_approximation_options => :german
10
+
11
+ state_machine do
12
+ state :draft
13
+ state :published
14
+ state :archived
15
+
16
+ event :publish do
17
+ transitions :to => :published, :from => [:draft, :archived], :on_transition => :set_published_at
18
+ end
19
+
20
+ event :unpublish do
21
+ transitions :to => :draft, :from => :published, :on_transition => :unset_published_at
22
+ end
23
+
24
+ event :archive do
25
+ transitions :to => :archived, :from => [:draft, :published], :on_transition => :set_archived_at
26
+ end
27
+
28
+ event :unarchive do
29
+ transitions :to => :draft, :from => :archived, :on_transition => :unset_archived_at
30
+ end
31
+
32
+ end
33
+
34
+
35
+ def available_events
36
+ Page.state_machines[:default].events_for(self.state.to_sym)
37
+ end
38
+
39
+
40
+ protected
41
+
42
+ before_save :transform
43
+
44
+ def transform
45
+ self.content_html = textilize self.content
46
+ end
47
+
48
+ def set_published_at
49
+ self.archived_at = nil
50
+ self.published_at = Time.now
51
+ end
52
+
53
+ def unset_published_at
54
+ self.published_at = nil
55
+ end
56
+
57
+ def set_archived_at
58
+ self.archived_at = Time.now
59
+ self.published_at = nil
60
+ end
61
+
62
+ def unset_archived_at
63
+ self.archived_at = nil
64
+ end
65
+
66
+ end
@@ -0,0 +1,6 @@
1
+ class Role < ActiveRecord::Base
2
+
3
+ ROLES = ["admin"]
4
+
5
+ acts_as_authorization_role
6
+ end
@@ -0,0 +1,48 @@
1
+ class Translation < ActiveRecord::Base
2
+
3
+ cattr_accessor :locales_config_path
4
+ self.locales_config_path = "#{Rails.root}/config/locales"
5
+
6
+ scope :pending, where('value is null')
7
+ scope :not_pending, where('value is not null')
8
+ scope :search_query, lambda {|query| where("key LIKE ? OR value LIKE ?", "%#{query}%", "%#{query}%") }
9
+
10
+ # create one yml per locale
11
+ def self.dump_all(to = self.locales_config_path)
12
+ I18n.available_locales.each do |locale|
13
+ File.open("#{to}/#{locale}.yml", "w+") do |file|
14
+ hash = to_hash(locale)
15
+ hash = { locale.to_s => {} }if hash.size == 0
16
+ YAML.dump(hash, file)
17
+ end
18
+ end
19
+ end
20
+
21
+ protected
22
+
23
+ def self.to_hash(locale)
24
+ hash = {}
25
+ translations = self.where(:locale => locale).where("value not null")
26
+ translations.each do |translation|
27
+ if translation.key.include?(".")
28
+ hash.deep_merge!(locale.to_s => unsquish(translation.key, translation.value))
29
+ else
30
+ hash.merge!(locale.to_s => { translation.key => translation.value })
31
+ end
32
+ end
33
+ hash
34
+ end
35
+
36
+ def self.unsquish(string, value)
37
+ if string.is_a?(String)
38
+ unsquish(string.split("."), value)
39
+ elsif string.size == 1
40
+ { string.first => value }
41
+ else
42
+ key = string[0]
43
+ rest = string[1..-1]
44
+ { key => unsquish(rest, value) }
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,42 @@
1
+ class User < ActiveRecord::Base
2
+ # Include default devise modules. Others available are:
3
+ # :token_authenticatable, :confirmable, :lockable and :timeoutable
4
+ devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
5
+
6
+ # Setup accessible (or protected) attributes for your model
7
+ attr_accessible :email, :password, :password_confirmation, :remember_me
8
+
9
+ acts_as_authorization_subject :association_name => :roles
10
+
11
+ scope :admins, where("roles.name = ?" , "admin").includes(:roles)
12
+
13
+ def role_list
14
+ roles = Role.all
15
+ user_roles = roles.map{|r| r if self.has_role?(r.name) }
16
+ end
17
+
18
+ def last_admin?
19
+ self.has_role?("admin") and User.admins.size == 1 ? true : false
20
+ end
21
+
22
+ def set_roles(roles)
23
+ if self.last_admin?
24
+ self.has_no_roles!
25
+ self.has_role!("admin")
26
+ else
27
+ self.has_no_roles!
28
+ end
29
+
30
+ return unless roles
31
+ for role in roles
32
+ self.has_role!(role)
33
+ end
34
+ end
35
+
36
+ protected
37
+
38
+ def password_required?
39
+ !persisted? || password.present? || password_confirmation.present?
40
+ end
41
+
42
+ end
@@ -0,0 +1,10 @@
1
+ <div id="nav">
2
+ <ul id="left">
3
+ <li><%= link_to t('.pages'), admin_pages_path %></li>
4
+ <li><%= link_to t('.categories'), admin_categories_path %></li>
5
+ <li><%= link_to t('.translations'), admin_translations_path %></li>
6
+ </ul>
7
+ <ul id="right">
8
+ <li><%= link_to t('.users'), admin_users_path %></li>
9
+ </ul>
10
+ </div>
@@ -0,0 +1,24 @@
1
+ <%= form_for [:admin, @category] do |f| %>
2
+ <%= render "shared/error_messages", :target => @category %>
3
+ <div>
4
+ <%= f.label :name, t('categories.name'), :class => "desc required" %>
5
+ <%= f.text_field :name, :size => "80" %>
6
+ </div>
7
+
8
+ <div>
9
+ <%= f.label :parent_id, t('categories.parent') %>
10
+ <%= f.select :parent_id, nested_set_options(Category, @category) {|i, level| "#{'-' * level} #{i.name}" } %>
11
+ </div>
12
+
13
+ <div>
14
+ <%= f.submit t('categories.submit') %>
15
+ <%= link_to t('cancel'), admin_categories_path %>
16
+ </div>
17
+ <% end %>
18
+
19
+ <% if @category.id && !@category.parent_id.nil? %>
20
+ <%= form_for [:admin, @category], :html => { :method => "delete" } do |f| %>
21
+ <input type="hidden" name="_method" value="delete" />
22
+ <button type="submit"><%= t('categories.delete') %></button>
23
+ <% end %>
24
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <h1><%= t('categories.edit.title') %></h1>
2
+
3
+ <%= render :partial => "form", :locals => { :category => @category } %>
@@ -0,0 +1,22 @@
1
+ <h1>Catégories</h1>
2
+
3
+ <p><%= link_to t('categories.links.new'), new_admin_category_path, :class => "button" %></p>
4
+
5
+ <table>
6
+ <tr>
7
+ <th><%= t('categories.name') %></th>
8
+ <th><%= t('categories.link') %></th>
9
+ <th></th>
10
+ </tr>
11
+ <%= render_cat @categories, :sort => lambda{|x| x.position } do |node, child| %>
12
+ <tr>
13
+ <td><%= display_node(node) %></td>
14
+ <td><%= node.link %></td>
15
+ <td>
16
+ <%= display_edit_category_link(node) %>
17
+ <%= display_sort_category_link(node) %>
18
+ </td>
19
+ </tr>
20
+ <%= child %>
21
+ <% end %>
22
+ </table>
@@ -0,0 +1,3 @@
1
+ <h1><%= t('categories.new.title') %></h1>
2
+
3
+ <%= render :partial => "form", :locals => { :category => @category } %>
@@ -0,0 +1,29 @@
1
+ <h1><%= t('categories.sort.title') %></h1>
2
+
3
+ <ul id="categories">
4
+ <% for category in @categories %>
5
+ <li id="category-<%= category.id %>"><span class='handle'>[drag]</span><%= category.name %></li>
6
+ <% end %>
7
+ </ul>
8
+
9
+ <p>
10
+ <%= link_to t('categories.sort.stop_sorting'), admin_categories_path %>
11
+ </p>
12
+
13
+
14
+ <% content_for (:head) do %>
15
+ <script type="text/javascript">
16
+ $(function() {
17
+
18
+ $('ul').sortable({items:'li',
19
+ axis: 'y',
20
+ dropOnEmpty: false,
21
+ complete: function(request){$('ul').effect('highlight');},
22
+ update: function() {
23
+ $.post("<%= sorting_admin_categories_path %>", '_method=get'+'&'+$(this).sortable('serialize'));
24
+ }}).disableSelection();
25
+
26
+ });
27
+
28
+ </script>
29
+ <% end %>
@@ -0,0 +1,25 @@
1
+ <%= form_for [:admin, @page] do |f| %>
2
+ <%= render "shared/error_messages", :target => @page %>
3
+ <div>
4
+ <%= f.label :title, t('pages.title'), :class => "desc required" %>
5
+ <%= f.text_field :title, :size => "80" %>
6
+ </div>
7
+ <div>
8
+ <%= f.label :category_id, t('pages.category') %>
9
+ <%= f.select :category_id, sorted_nested_set_options(Category, lambda(&:name)) {|i, level| "#{'-' * level} #{i.name}" } %>
10
+ </div>
11
+ <div>
12
+ <%= f.text_area :content, :size => "60x30" %>
13
+ </div>
14
+ <div>
15
+ <%= f.submit t('pages.submit') %>
16
+ <%= link_to t('cancel'), admin_pages_path %>
17
+ </div>
18
+ <% end %>
19
+
20
+ <% if @page.id %>
21
+ <%= form_for [:admin, @page], :html => { :method => "delete" } do |f| %>
22
+ <input type="hidden" name="_method" value="delete" />
23
+ <button type="submit"><%= t('pages.delete') %></button>
24
+ <% end %>
25
+ <% end %>