From 76a409705b02986f6f21a484cdb9052211f77e4b Mon Sep 17 00:00:00 2001 From: Mathias Gawlista Date: Thu, 26 Mar 2015 21:40:06 +0100 Subject: [PATCH] refs #7 Adds new model Page. Replaces Page Modules page by Pages (Pages & Modules) page and show here a tab pane including pages, module collections and modules. --- .../index.js.coffee | 0 .../page_module_collections_controller.rb | 20 +--- app/controllers/pages_controller.rb | 95 +++++++++++++++++++ app/helpers/home_page/application_helper.rb | 4 + app/models/page.rb | 31 ++++++ app/views/pages/_collection.html.erb | 18 ++++ app/views/pages/_fields.html.erb | 4 + app/views/pages/_form.html.erb | 25 +++++ app/views/pages/_page.html.erb | 35 +++++++ app/views/pages/_tab.html.erb | 39 ++++++++ app/views/pages/destroy.js.erb | 9 ++ app/views/pages/edit.html.erb | 3 + .../index.html.erb | 37 +++++++- app/views/pages/new.html.erb | 3 + app/views/pages/show.html.erb | 3 + app/views/pages/update.js.erb | 11 +++ config/locales/resources/page/en.yml | 16 ++++ .../resources/page_module_collection/en.yml | 1 + config/routes.rb | 2 + db/migrate/20150325183940_create_pages.rb | 13 +++ dummy/Gemfile.lock | 2 + ...325184310_create_pages.home_page_engine.rb | 14 +++ home_page.gemspec | 3 +- lib/home_page.rb | 1 + lib/home_page/navigation.rb | 76 +++++++++------ 25 files changed, 415 insertions(+), 50 deletions(-) rename app/assets/javascripts/home_page/{page_module_collections => pages}/index.js.coffee (100%) create mode 100644 app/controllers/pages_controller.rb create mode 100644 app/models/page.rb create mode 100644 app/views/pages/_collection.html.erb create mode 100644 app/views/pages/_fields.html.erb create mode 100644 app/views/pages/_form.html.erb create mode 100644 app/views/pages/_page.html.erb create mode 100644 app/views/pages/_tab.html.erb create mode 100644 app/views/pages/destroy.js.erb create mode 100644 app/views/pages/edit.html.erb rename app/views/{page_module_collections => pages}/index.html.erb (66%) create mode 100644 app/views/pages/new.html.erb create mode 100644 app/views/pages/show.html.erb create mode 100644 app/views/pages/update.js.erb create mode 100644 config/locales/resources/page/en.yml create mode 100644 db/migrate/20150325183940_create_pages.rb create mode 100644 dummy/db/migrate/20150325184310_create_pages.home_page_engine.rb diff --git a/app/assets/javascripts/home_page/page_module_collections/index.js.coffee b/app/assets/javascripts/home_page/pages/index.js.coffee similarity index 100% rename from app/assets/javascripts/home_page/page_module_collections/index.js.coffee rename to app/assets/javascripts/home_page/pages/index.js.coffee diff --git a/app/controllers/page_module_collections_controller.rb b/app/controllers/page_module_collections_controller.rb index c8551e3..d468f8d 100644 --- a/app/controllers/page_module_collections_controller.rb +++ b/app/controllers/page_module_collections_controller.rb @@ -5,21 +5,11 @@ class PageModuleCollectionsController < ApplicationController before_filter :show_breadcrumbs, except: :index def index - slug_stub = if params[:slug_stub].blank? - @page_module_collection_slug_stubs = PageModuleCollection.pluck(:slug_stub).uniq.sort - @page_module_collection_slug_stubs.first - else - params[:slug_stub] - end + redirect_to pages_path if params[:slug_stub].blank? - @page_module_collections = PageModuleCollection.where(slug_stub: slug_stub).paginate(page: params[:page], per_page: 10) - - if params[:slug_stub].blank? - @page_module_slug_stubs = PageModule.pluck(:slug_stub).uniq.sort - @page_modules = PageModule.where(slug_stub: @page_module_slug_stubs.first).paginate(page: params[:module_page], per_page: 10) - end + @page_module_collections = PageModuleCollection.where(slug_stub: params[:slug_stub]).paginate(page: params[:page], per_page: 10) - render partial: 'page_module_collections/collection', layout: false if params[:slug_stub].present? + render partial: 'page_module_collections/collection', layout: false end def new @@ -30,10 +20,10 @@ def create @page_module_collection = PageModuleCollection.create(params[:page_module_collection]) if @page_module_collection.persisted? - @path = page_module_collections_path + @path = page_module_collections_path(slug_stub: @page_module_collection.slug_stub) if request.xhr? - @target = '#page' + @target = "#page_module_collections_slug_stub_#{@page_module_collection.slug_stub}" @close_modal = true end else diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb new file mode 100644 index 0000000..ceff22d --- /dev/null +++ b/app/controllers/pages_controller.rb @@ -0,0 +1,95 @@ +class PagesController < ApplicationController + respond_to :html, :js + + before_filter :authenticate_user!, except: [:show] + before_filter :show_breadcrumbs + + def index + @pages = Page.paginate(page: params[:page], per_page: 10) + + if params[:page].blank? + @page_module_collection_slug_stubs = PageModuleCollection.pluck(:slug_stub).uniq.sort + slug_stub = @page_module_collection_slug_stubs.first + @page_module_collections = PageModuleCollection.where(slug_stub: slug_stub).paginate(page: params[:page], per_page: 10) + @page_module_slug_stubs = PageModule.pluck(:slug_stub).uniq.sort + @page_modules = PageModule.where(slug_stub: @page_module_slug_stubs.first).paginate(page: params[:module_page], per_page: 10) + else + render partial: 'pages/collection', layout: false + end + end + + def new + @page = Page.new(params[:page]) + end + + def create + @page = Page.create(params[:page]) + + if @page.persisted? + @path = pages_path(page: 1) + + if request.xhr? + @target = '#pages_container' + @close_modal = true + end + else + @template = :new + + if request.xhr? + @target = '.modal-content' + @target_needs_modal_layout = false + end + end + + render_or_redirect_by_request_type + end + + def show + @page = Page.friendly.find(params[:id]) + end + + def edit + @page = Page.friendly.find(params[:id]) + end + + def update + @page = Page.friendly.find(params[:id]) + + if @page.update_attributes(params[:page]) + flash[:notice] = t('general.form.successfully_updated') + + if request.xhr? + @template_format = 'js' + else + @path = edit_page_path(@page_module) + end + else + @template = :edit + @target = '.modal-content' if request.xhr? + end + + render_or_redirect_by_request_type + end + + def destroy + @page = Page.friendly.find(params[:id]).destroy + + if @page.persisted? + flash[:alert] = I18n.t('general.form.destroy_failed') + else + flash[:notice] = I18n.t('general.form.destroyed') + end + + redirect_to pages_path unless request.xhr? + end + + def resource + @page + end + + protected + + def show_breadcrumbs + @show_breadcrumbs = true if user_signed_in? + end +end \ No newline at end of file diff --git a/app/helpers/home_page/application_helper.rb b/app/helpers/home_page/application_helper.rb index 8cdfdf5..98434a3 100644 --- a/app/helpers/home_page/application_helper.rb +++ b/app/helpers/home_page/application_helper.rb @@ -78,5 +78,9 @@ def attribute_translation(attribute, current_resource = nil) default: t("attributes.#{attribute}") ) end + + def liquidize(content, arguments = {}) + RedCloth.new(Liquid::Template.parse(content).render(arguments)).to_html + end end end \ No newline at end of file diff --git a/app/models/page.rb b/app/models/page.rb new file mode 100644 index 0000000..33ca2b9 --- /dev/null +++ b/app/models/page.rb @@ -0,0 +1,31 @@ +class Page < ActiveRecord::Base + serialize :data, Hash + + validates :title, presence: true, uniqueness: true + validates :content, presence: true + + validate :valid_liquid_syntax + + attr_accessible :title, :content, :data + + extend FriendlyId + + friendly_id :title, use: :slugged + + private + + def valid_liquid_syntax + Liquid::Template.parse(content) + rescue Liquid::SyntaxError => e + errors.add( + :content, + I18n.t( + 'activerecord.errors.models.page_module.attributes.content.liquid_syntax_invalid', message: e.message + ) + ) + end + + def should_generate_new_friendly_id? + title_changed? + end +end \ No newline at end of file diff --git a/app/views/pages/_collection.html.erb b/app/views/pages/_collection.html.erb new file mode 100644 index 0000000..a895c76 --- /dev/null +++ b/app/views/pages/_collection.html.erb @@ -0,0 +1,18 @@ +<% if @pages.none? %> +

<%= t('pages.index.empty_collection') %>

+<% else %> + + + '> + + + + + + + <%= render partial: 'pages/page', collection: @pages %> + +
<%= t('general.attributes.title') %><%= t('general.attributes.slug') %>
+ + <%= will_paginate @pages, renderer: BootstrapPagination::Rails %> +<% end %> diff --git a/app/views/pages/_fields.html.erb b/app/views/pages/_fields.html.erb new file mode 100644 index 0000000..5442cf2 --- /dev/null +++ b/app/views/pages/_fields.html.erb @@ -0,0 +1,4 @@ +<%= devise_error_messages! %> + +<%= f.input :title %> +<%= f.input :content %> \ No newline at end of file diff --git a/app/views/pages/_form.html.erb b/app/views/pages/_form.html.erb new file mode 100644 index 0000000..652e7c1 --- /dev/null +++ b/app/views/pages/_form.html.erb @@ -0,0 +1,25 @@ +<% content_for :modal_footer do %> + + +<% end %> + +<%= simple_form_for( + resource, url: resource.new_record? ? pages_path : page_path(resource), wrapper: :horizontal_form, + method: resource.new_record? ? :post : :put, remote: request.xhr?, html: { class: 'form-horizontal', autocomplete: 'off' } +) do |f| %> + <% if request.xhr? %> + <% content_for :modal_body do %> + <%= render partial: 'pages/fields', locals: { f: f } %> + <% end %> + + <%= render partial: 'shared/layouts/modal' %> + <% else %> + <%= render partial: 'pages/fields', locals: { f: f } %> + +
+
+ +
+
+ <% end %> +<% end %> \ No newline at end of file diff --git a/app/views/pages/_page.html.erb b/app/views/pages/_page.html.erb new file mode 100644 index 0000000..cffaf1b --- /dev/null +++ b/app/views/pages/_page.html.erb @@ -0,0 +1,35 @@ + + + <%= link_to page.title, page_path(page) %> + + + <%= page.slug %> + + + + + \ No newline at end of file diff --git a/app/views/pages/_tab.html.erb b/app/views/pages/_tab.html.erb new file mode 100644 index 0000000..d89056f --- /dev/null +++ b/app/views/pages/_tab.html.erb @@ -0,0 +1,39 @@ +

+<% if @page_module_slug_stubs.none? %> +

+<% else %> +
+ +
+ <% @page_module_slug_stubs.each_with_index do |slug_stub, index| %> +
+ <%= render partial: 'page_modules/collection' if index == 0 %> +
+ <% end %> +
+
+<% end %> +

+ +

+ +

\ No newline at end of file diff --git a/app/views/pages/destroy.js.erb b/app/views/pages/destroy.js.erb new file mode 100644 index 0000000..71c25d5 --- /dev/null +++ b/app/views/pages/destroy.js.erb @@ -0,0 +1,9 @@ +<% message = flash[:notice] || flash[:alert] %> +<% flash.delete(:notice); flash.delete(:alert) %> +<% alert = message.present? ? "alert('#{message}');" : '' %> + +<% unless @page.persisted? %> + $("#pages_row_<%= @page.id %>").remove(); +<% end %> + +<%= raw alert %> \ No newline at end of file diff --git a/app/views/pages/edit.html.erb b/app/views/pages/edit.html.erb new file mode 100644 index 0000000..f5fe882 --- /dev/null +++ b/app/views/pages/edit.html.erb @@ -0,0 +1,3 @@ +<% content_for :title do %><%= t('pages.edit.title') %><% end %> + +<%= render partial: 'pages/form' %> \ No newline at end of file diff --git a/app/views/page_module_collections/index.html.erb b/app/views/pages/index.html.erb similarity index 66% rename from app/views/page_module_collections/index.html.erb rename to app/views/pages/index.html.erb index 549fb49..147dd5c 100644 --- a/app/views/page_module_collections/index.html.erb +++ b/app/views/pages/index.html.erb @@ -1,20 +1,47 @@ -<% content_for :title do %><%= t('page_modules.index.title') %><% end %> +<% content_for :title do %><%= t('pages.index.long_title') %><% end %>
-
+
+
+<% if @pages.none? %> +

+

+

+<% else %> + <%= render partial: 'pages/collection' %> +<% end %> +
+ +

+ +

+
+

<% if @page_module_collection_slug_stubs.none? %>

<% content_for :javascript_includes do %> - <%= javascript_include_tag 'home_page/page_module_collections/index' %> + <%= javascript_include_tag 'home_page/pages/index' %> <% end %> \ No newline at end of file diff --git a/app/views/pages/new.html.erb b/app/views/pages/new.html.erb new file mode 100644 index 0000000..cef7972 --- /dev/null +++ b/app/views/pages/new.html.erb @@ -0,0 +1,3 @@ +<% content_for :title do %><%= t('pages.new.title') %><% end %> + +<%= render partial: 'pages/form' %> \ No newline at end of file diff --git a/app/views/pages/show.html.erb b/app/views/pages/show.html.erb new file mode 100644 index 0000000..e6e130c --- /dev/null +++ b/app/views/pages/show.html.erb @@ -0,0 +1,3 @@ +<% content_for :title do %><%= @page.title %><% end %> + +<%= raw liquidize(@page.content) %> \ No newline at end of file diff --git a/app/views/pages/update.js.erb b/app/views/pages/update.js.erb new file mode 100644 index 0000000..3d119fa --- /dev/null +++ b/app/views/pages/update.js.erb @@ -0,0 +1,11 @@ +<% message = flash[:notice] %> +<% flash.delete(:notice) %> +<% alert = message.present? ? "alert('#{message}');" : '' %> + +$("#pages_row_<%= @page.id %>").replaceWith("<%= escape_javascript( + render( + partial: 'pages/page', locals: { page: @page } + ) +) %>"); +$('#modal').modal('hide'); +<%= raw alert %> \ No newline at end of file diff --git a/config/locales/resources/page/en.yml b/config/locales/resources/page/en.yml new file mode 100644 index 0000000..df6ec65 --- /dev/null +++ b/config/locales/resources/page/en.yml @@ -0,0 +1,16 @@ +en: + pages: + index: + title: Pages + long_title: Pages & Modules + empty_collection: No pages available. + + new: + title: New Page + + edit: + title: Edit Page + + activerecord: + models: + page: Page diff --git a/config/locales/resources/page_module_collection/en.yml b/config/locales/resources/page_module_collection/en.yml index fc73dd7..b34643d 100644 --- a/config/locales/resources/page_module_collection/en.yml +++ b/config/locales/resources/page_module_collection/en.yml @@ -2,6 +2,7 @@ en: page_module_collections: index: title: Page Module Collections + medium_title: Module Collections short_title: Collections empty_collection: No page module collections available. diff --git a/config/routes.rb b/config/routes.rb index a5c433d..4a57a44 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,6 +4,8 @@ sessions: 'devise_extensions/sessions' } + resources :pages + resources :page_module_collections do resources :modules, controller: 'page_modules', only: [:index, :new] do collection do diff --git a/db/migrate/20150325183940_create_pages.rb b/db/migrate/20150325183940_create_pages.rb new file mode 100644 index 0000000..c20dc66 --- /dev/null +++ b/db/migrate/20150325183940_create_pages.rb @@ -0,0 +1,13 @@ +class CreatePages < ActiveRecord::Migration + def change + create_table :pages do |t| + t.string :slug + t.string :title + t.text :content + t.text :data, limit: 16777215 + t.timestamps + end + + add_index :pages, :slug, unique: true + end +end diff --git a/dummy/Gemfile.lock b/dummy/Gemfile.lock index 945517b..f89cf48 100644 --- a/dummy/Gemfile.lock +++ b/dummy/Gemfile.lock @@ -14,6 +14,7 @@ PATH remote: /Users/gawlim/workspace/home_page/home_page specs: home_page (0.0.6) + RedCloth (~> 4.2.9) activerecord-deprecated_finders (~> 1.0.3) acts_as_list (~> 0.4.0) albino (~> 1.3.3) @@ -49,6 +50,7 @@ GEM remote: http://gems.github.com/ remote: http://rubygems.org/ specs: + RedCloth (4.2.9) actionmailer (4.2.0) actionpack (= 4.2.0) actionview (= 4.2.0) diff --git a/dummy/db/migrate/20150325184310_create_pages.home_page_engine.rb b/dummy/db/migrate/20150325184310_create_pages.home_page_engine.rb new file mode 100644 index 0000000..0544173 --- /dev/null +++ b/dummy/db/migrate/20150325184310_create_pages.home_page_engine.rb @@ -0,0 +1,14 @@ +# This migration comes from home_page_engine (originally 20150325183940) +class CreatePages < ActiveRecord::Migration + def change + create_table :pages do |t| + t.string :slug + t.string :title + t.text :content + t.text :data, limit: 16777215 + t.timestamps + end + + add_index :pages, :slug, unique: true + end +end diff --git a/home_page.gemspec b/home_page.gemspec index 4799a7c..fcf1f6c 100644 --- a/home_page.gemspec +++ b/home_page.gemspec @@ -47,7 +47,8 @@ Gem::Specification.new do |s| s.add_dependency 'will_paginate-bootstrap', '~> 1.0.1' s.add_dependency 'turbolinks', '~> 2.5.3' s.add_dependency 'liquid', '~> 3.0.1' - + s.add_dependency 'RedCloth', '~> 4.2.9' + # CSS & JavaScript s.add_dependency 'twitter-bootswatch-rails', '~> 3.3.2.0' s.add_dependency 'twitter-bootswatch-rails-fontawesome', '~> 4.3.0.0' diff --git a/lib/home_page.rb b/lib/home_page.rb index 10738bf..d8e59c7 100644 --- a/lib/home_page.rb +++ b/lib/home_page.rb @@ -28,6 +28,7 @@ require 'liquid' require 'selectize-rails' require 'acts_as_list' +require 'redcloth' require 'home_page/api_provider_host' require 'home_page/navigation' diff --git a/lib/home_page/navigation.rb b/lib/home_page/navigation.rb index 5bdeaf7..c75a913 100644 --- a/lib/home_page/navigation.rb +++ b/lib/home_page/navigation.rb @@ -27,7 +27,7 @@ def self.code Proc.new do |navigation| navigation.items do |primary, options| primary.dom_class = 'nav navbar-nav' - + Setting['home_page.general.navigation.items'].each do |item| klass = "HomePage#{item.is_a?(Array) ? item.first.classify : ''}::Navigation" item = item.is_a?(Array) ? item.last : item @@ -39,40 +39,58 @@ def self.code def self.menu_code(resource) case resource - when 'page_modules' + when 'pages', 'page_modules' Proc.new do |primary, options| if user_signed_in? - primary.item( - :page_module_collections, t('page_modules.index.title'), page_module_collections_path, - breadcrumb_title: t('page_module_collections.index.title') - ) do |page_module_collections| - page_module_collections.item :new, t('general.new'), new_page_module_collection_path + primary.item :pages, t('pages.index.title'), pages_path do |pages| + pages.item :new, t('general.new'), new_page_path - unless (@page_module_collection.new_record? rescue true) - page_module_collections.item( - :show, @page_module_collection.title, page_module_collection_path(@page_module_collection) - ) do |page_module_collection| - page_module_collection.item( - :edit, t('general.edit'), edit_page_module_collection_path(@page_module_collection) + unless (@page.new_record? rescue true) + pages.item( + :show, @page.title, page_path(@page) + ) do |page| + page.item( + :edit, t('general.edit'), edit_page_path(@page) ) - page_module_collection.item( - :destroy, t('general.destroy'), page_module_collection_path(@page_module_collection), method: :delete, + page.item( + :destroy, t('general.destroy'), page_path(@page), method: :delete, confirm: t('general.questions.are_you_sure') ) - - page_module_collection.item( - :new_module, t('page_modules.new.short_title'), new_page_module_collection_module_path(@page_module_collection) - ) - - page_module_collection.item( - :modules, t('page_modules.index.short_title'), page_module_collection_modules_path(@page_module_collection) - ) do |page_modules| - unless (@page_module.new_record? rescue true) - page_modules.item :edit, t('general.edit'), edit_page_module_path(@page_module) do |page_module| - page_module.item( - :destroy, t('general.destroy'), page_module_path(@page_module), method: :delete, - confirm: t('general.questions.are_you_sure') - ) + end + end + + pages.item( + :page_module_collections, t('page_module_collections.index.medium_title'), page_module_collections_path, + breadcrumb_title: t('page_module_collections.index.short_title') + ) do |page_module_collections| + page_module_collections.item :new, t('general.new'), new_page_module_collection_path + + unless (@page_module_collection.new_record? rescue true) + page_module_collections.item( + :show, @page_module_collection.title, page_module_collection_path(@page_module_collection) + ) do |page_module_collection| + page_module_collection.item( + :edit, t('general.edit'), edit_page_module_collection_path(@page_module_collection) + ) + page_module_collection.item( + :destroy, t('general.destroy'), page_module_collection_path(@page_module_collection), method: :delete, + confirm: t('general.questions.are_you_sure') + ) + + page_module_collection.item( + :new_module, t('page_modules.new.short_title'), new_page_module_collection_module_path(@page_module_collection) + ) + + page_module_collection.item( + :modules, t('page_modules.index.short_title'), page_module_collection_modules_path(@page_module_collection) + ) do |page_modules| + unless (@page_module.new_record? rescue true) + page_modules.item :edit, t('general.edit'), edit_page_module_path(@page_module) do |page_module| + page_module.item( + :destroy, t('general.destroy'), page_module_path(@page_module), method: :delete, + confirm: t('general.questions.are_you_sure') + ) + end end end end