semistatic 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +112 -0
  4. data/Rakefile +27 -0
  5. data/app/assets/javascripts/semistatic/pages.js +2 -0
  6. data/app/assets/javascripts/semistatic/semistatic.js +16 -0
  7. data/app/assets/stylesheets/semistatic/application.css +13 -0
  8. data/app/assets/stylesheets/semistatic/pages.css +4 -0
  9. data/app/controllers/semistatic/application_controller.rb +4 -0
  10. data/app/controllers/semistatic/page_view_controller.rb +7 -0
  11. data/app/controllers/semistatic/pages_controller.rb +7 -0
  12. data/app/helpers/semistatic/application_helper.rb +4 -0
  13. data/app/models/semistatic/page.rb +40 -0
  14. data/app/models/semistatic/part.rb +54 -0
  15. data/app/views/layouts/semistatic/application.html.erb +13 -0
  16. data/app/views/semistatic/page_view/show.html.erb +2 -0
  17. data/app/views/semistatic/pages/_form.html.erb +46 -0
  18. data/app/views/semistatic/pages/edit.html.erb +6 -0
  19. data/app/views/semistatic/pages/index.html.erb +27 -0
  20. data/app/views/semistatic/pages/new.html.erb +5 -0
  21. data/app/views/semistatic/pages/show.html.erb +27 -0
  22. data/config/routes.rb +7 -0
  23. data/config/tinymce.yml +9 -0
  24. data/db/migrate/20130121193153_create_semistatic_pages.rb +10 -0
  25. data/db/migrate/20130122144450_add_template_name_to_pages.rb +5 -0
  26. data/db/migrate/20130122165327_create_semistatic_parts.rb +18 -0
  27. data/db/migrate/20130123191541_add_options_to_parts.rb +5 -0
  28. data/db/migrate/20130128113556_add_layout_to_pages.rb +5 -0
  29. data/lib/semistatic.rb +38 -0
  30. data/lib/semistatic/concerns/controllers/page_view_controller.rb +30 -0
  31. data/lib/semistatic/concerns/controllers/pages_controller.rb +83 -0
  32. data/lib/semistatic/configuration.rb +59 -0
  33. data/lib/semistatic/engine.rb +11 -0
  34. data/lib/semistatic/presenters/page_presenter.rb +79 -0
  35. data/lib/semistatic/version.rb +3 -0
  36. data/lib/tasks/semistatic_tasks.rake +4 -0
  37. metadata +261 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 65c3e7f739547de2e8412c7756ba07bb68c4bc2d
4
+ data.tar.gz: 59dc58881c726911e141aa45f3d12ec78fe89b59
5
+ SHA512:
6
+ metadata.gz: 94eca23e63429ebd5356ee998b7767ca7bdb7294770c28fb0e4d95e58b9719209b7163b7d551252e2ad5c215745926eb71ee6a80080350bfd02cbd3dd1d6542e
7
+ data.tar.gz: d70564bb7f7665fffbd2dd985ee2fc4a19ec3a354bcfe1e53df745f8bce45c5b9f62bb5f17e644b36b40d80fe133fddf444d6a0500afcff023181c7963c8f524
@@ -0,0 +1,20 @@
1
+ Copyright 2013 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,112 @@
1
+ Semistatic
2
+ =============
3
+
4
+ [![Build Status](https://travis-ci.org/mjacobus/semistatic.png?branch=master)](https://travis-ci.org/mjacobus/semistatic)
5
+ [![Coverage Status](https://coveralls.io/repos/mjacobus/semistatic/badge.png)](https://coveralls.io/r/mjacobus/semistatic)
6
+ [![Code Climate](https://codeclimate.com/github/mjacobus/semistatic.png)](https://codeclimate.com/github/mjacobus/semistatic)
7
+ [![Dependency Status](https://gemnasium.com/mjacobus/semistatic.png)](https://gemnasium.com/mjacobus/semistatic)
8
+ [![Gem Version](https://badge.fury.io/rb/semistatic.png)](http://badge.fury.io/rb/semistatic)
9
+
10
+ Provides a kind a simple way of creating editable pages.
11
+
12
+ ## Instalation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ ```ruby
17
+ gem 'semistatic'
18
+ ```
19
+
20
+ And then run:
21
+
22
+ bundle install
23
+ rake semistatic:install:migrations
24
+ rake db:migrate
25
+
26
+ On the application route file
27
+ -----------------------------
28
+
29
+ ```ruby
30
+ Rails.application.routes.draw do
31
+ match ':slug.html' => 'semistatic/page_view#show', as: :page
32
+ mount Semistatic::Engine => "/admin"
33
+ end
34
+ ```
35
+
36
+ The config file
37
+ -----------------------------
38
+
39
+ ```yml
40
+ #config/semistatic.yaml
41
+ pages:
42
+ about:
43
+ parts:
44
+ title:
45
+ type: String
46
+ body:
47
+ type: Html
48
+ profile:
49
+ parts:
50
+ avatar:
51
+ type: image
52
+ # paperclip styles. Use the original key to set the image size
53
+ styles:
54
+ original: 200x200>
55
+ thumb: 50x50>
56
+ about:
57
+ type: html
58
+ slogan:
59
+ type: string
60
+ ```
61
+
62
+ The templates
63
+ -----------------------------
64
+
65
+ Create the templates inside app/views/templates. Use the the @presenter instance val to
66
+ ouput the field content with <%= @presenter.output(:field_name) %>
67
+
68
+ about page: app/views/layouts/templates/about.html.erb
69
+
70
+ ```html
71
+ <h1><%= @presenter.output(:page_title) %></h1>
72
+
73
+ <div class="body">
74
+ <%= @presenter.output(:body) %>
75
+ </div>
76
+ ```
77
+
78
+ profile page: app/views/layouts/templates/profile.html.erb
79
+
80
+ ```ruby
81
+ <h1><%= @presenter.output(:page_title) %></h1>
82
+
83
+ <figure>
84
+ <%= @presenter.output(:avatar) %>
85
+ </figure>
86
+
87
+ <p class="slogan"><%= @presenter.output(:slogan) %></p>
88
+
89
+ <div class="about"><%= @presenter.output(:about) %></div>
90
+ ```
91
+
92
+ Overriding the controller
93
+ -----------------------------
94
+
95
+ Semistatic uses the ActiveSupport::Concearn pattern to extend its functionalities.
96
+
97
+ To override, say, the crud controller, should create a file
98
+ app/controllers/semistatic/pages_controller.rb with the following content:
99
+
100
+ ```ruby
101
+ # app/controllers/semistatic/pages_controller.rb
102
+
103
+ module Semistatic
104
+ class PartsController < ApplicationController
105
+ include Semistatic::Concerns::Controller::PartsController
106
+
107
+ included do
108
+ before_filter :require_authentication
109
+ end
110
+ end
111
+ end
112
+ ```
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Semistatic'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+
24
+
25
+
26
+ Bundler::GemHelper.install_tasks
27
+
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,16 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require tinymce-jquery
16
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ module Semistatic
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ require_dependency "semistatic/application_controller"
2
+
3
+ module Semistatic
4
+ class PageViewController < ApplicationController
5
+ include Semistatic::Concerns::Controllers::PageViewController
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require_dependency "semistatic/application_controller"
2
+
3
+ module Semistatic
4
+ class PagesController < ApplicationController
5
+ include Semistatic::Concerns::Controllers::PagesController
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ module Semistatic
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,40 @@
1
+ module Semistatic
2
+ class Page < ActiveRecord::Base
3
+ attr_accessible :layout,
4
+ :parts_attributes,
5
+ :slug,
6
+ :template_name,
7
+ :title
8
+
9
+ has_many :parts
10
+ accepts_nested_attributes_for :parts
11
+
12
+ validates :slug, presence: true, uniqueness: { case_sensitive: false }
13
+ validates :title, presence: true
14
+
15
+ # get part by its name
16
+ # param
17
+ # @return Part
18
+ def part(name)
19
+ parts.select {|p| p.name.downcase == name.to_s.downcase }.first
20
+ end
21
+
22
+ # Factory a page from the config
23
+ # Creates the attributes required by the config
24
+ # @param String template_name
25
+ # @param Hash options # the page configuration
26
+ # @return Page
27
+ def self.factory(template_name, options)
28
+ page = new(template_name: template_name)
29
+
30
+ options = HashWithIndifferentAccess.new(options)
31
+ options[:parts].each do |name, attributes|
32
+ part = page.parts.build({ name: name })
33
+ part.options = attributes
34
+ end
35
+
36
+ page.save(validate: false)
37
+ page
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,54 @@
1
+ module Semistatic
2
+ class Part < ActiveRecord::Base
3
+ belongs_to :page
4
+ attr_accessible :name, :value, :file
5
+
6
+ serialize :options, Hash
7
+
8
+ has_attached_file :file,
9
+ styles: lambda { |attachment| attachment.instance.options[:styles] || {} }
10
+
11
+ # attachment validation
12
+ validates_attachment_presence :file, if: :is_file?
13
+ validates_attachment_size :file, :less_than => 5.megabytes
14
+ # TODO: Learn how to validate depending on the options, lambda maybe
15
+ validates_attachment_content_type :file, content_type: ['image/jpeg', 'image/png', 'image/gif']
16
+
17
+ validates :name, presence: true, uniqueness: { case_sensitive: false, scope: :page_id }
18
+ validates :page, presence: true
19
+
20
+
21
+ # is this is an image?
22
+ def is_image?
23
+ type == :image
24
+ end
25
+
26
+ # is this a file?
27
+ def is_file?
28
+ is_image? || type == :file
29
+ end
30
+
31
+ # @return Symbol
32
+ def type
33
+ options[:type].to_sym if options[:type]
34
+ end
35
+
36
+ # force options to be a HashWithIndifferentAccess
37
+ # @param (nil | Hash | HashWithIndifferentAccess)
38
+ def options=(options)
39
+ if options.respond_to? :deep_symbolize_keys
40
+ options = options.deep_symbolize_keys
41
+ end
42
+ write_attribute(:options, options)
43
+ end
44
+
45
+
46
+ def valid_content_type
47
+ if is_image?
48
+ ['image/jpg', 'image/png', 'image/gif']
49
+ else
50
+ []
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Semistatic</title>
5
+ <%= stylesheet_link_tag "semistatic/application", :media => "all" %>
6
+ <%= csrf_meta_tags %>
7
+ </head>
8
+ <body>
9
+
10
+ <%= yield %>
11
+
12
+ </body>
13
+ </html>
@@ -0,0 +1,2 @@
1
+ <h1>PageView#show</h1>
2
+ <p>Find me in semistaticpage_view/show.html.erb</p>
@@ -0,0 +1,46 @@
1
+ <%= javascript_include_tag "semistatic/semistatic" %>
2
+ <%= tinymce %>
3
+
4
+ <%= form_for(@page) do |f| %>
5
+ <% if @page.errors.any? %>
6
+ <div id="error_explanation">
7
+ <h2><%= pluralize(@page.errors.count, "error") %> prohibited this page from being saved:</h2>
8
+
9
+ <ul>
10
+ <% @page.errors.full_messages.each do |msg| %>
11
+ <li><%= msg %></li>
12
+ <% end %>
13
+ </ul>
14
+ </div>
15
+ <% end %>
16
+
17
+ <div class="field">
18
+ <%= f.label :title %><br />
19
+ <%= f.text_field :title %>
20
+ </div>
21
+
22
+ <div class="field">
23
+ <%= f.label :slug %><br />
24
+ <%= f.text_field :slug %>
25
+ </div>
26
+
27
+ <div class="field">
28
+ <%= f.label :layout %><br />
29
+ <%= f.text_field :layout %>
30
+ </div>
31
+
32
+
33
+ <fieldset>
34
+ <legend>Page Parts</legend>
35
+ <%= f.fields_for :parts do |subform| %>
36
+ <div class="field">
37
+ <%= subform.label(subform.object.name) %><br />
38
+ <%= @presenter.input(subform) %>
39
+ </div>
40
+ <% end %>
41
+ </fieldset>
42
+
43
+ <div class="actions">
44
+ <%= f.submit %>
45
+ </div>
46
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing page</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Show', @page %> |
6
+ <%= link_to 'Back', pages_path %>
@@ -0,0 +1,27 @@
1
+ <h1>Listing pages</h1>
2
+
3
+ <ul>
4
+ <% @config.pages.each do |name, config| %>
5
+ <li><%= link_to(name.to_s.titleize, new_page_path(template_name: name)) %></li>
6
+ <% end %>
7
+ </ul>
8
+
9
+ <table class="table">
10
+ <tr>
11
+ <th>Title</th>
12
+ <th>Slug</th>
13
+ <th></th>
14
+ <th></th>
15
+ <th></th>
16
+ </tr>
17
+
18
+ <% @pages.each do |page| %>
19
+ <tr>
20
+ <td><%= page.title %></td>
21
+ <td><%= page.slug %></td>
22
+ <td><%= link_to 'Show', page %></td>
23
+ <td><%= link_to 'Edit', edit_page_path(page) %></td>
24
+ <td><%= link_to 'Destroy', page, method: :delete, data: { confirm: 'Are you sure?' } %></td>
25
+ </tr>
26
+ <% end %>
27
+ </table>
@@ -0,0 +1,5 @@
1
+ <h1>New page</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Back', pages_path %>
@@ -0,0 +1,27 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <p>
4
+ <b>Title:</b>
5
+ <%= @page.title %>
6
+ </p>
7
+
8
+ <p>
9
+ <b>Slug:</b>
10
+ <%= @page.slug %>
11
+ </p>
12
+
13
+ <p>
14
+ <b>Layout:</b>
15
+ <%= @page.layout %>
16
+ </p>
17
+
18
+
19
+ <% @page.parts.each do |part| %>
20
+ <div class="semistatic-part">
21
+ <h2 class="zpart-name"><%= part.name %></h2>
22
+ <div class="content"><%= @presenter.output(part.name) %></div>
23
+ </div>
24
+ <% end %>
25
+
26
+ <%= link_to 'Edit', edit_page_path(@page) %> |
27
+ <%= link_to 'Back', pages_path %>
@@ -0,0 +1,7 @@
1
+ Semistatic::Engine.routes.draw do
2
+ get "page_view/show"
3
+
4
+ resources :pages
5
+
6
+
7
+ end
@@ -0,0 +1,9 @@
1
+ theme_advanced_toolbar_location: top
2
+ theme_advanced_toolbar_align: left
3
+ theme_advanced_statusbar_location: bottom
4
+ theme_advanced_buttons3_add:
5
+ - tablecontrols
6
+ - fullscreen
7
+ plugins:
8
+ - table
9
+ - fullscreen
@@ -0,0 +1,10 @@
1
+ class CreateSemistaticPages < ActiveRecord::Migration
2
+ def change
3
+ create_table :semistatic_pages do |t|
4
+ t.string :title
5
+ t.string :slug
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ class AddTemplateNameToPages < ActiveRecord::Migration
2
+ def change
3
+ add_column :semistatic_pages, :template_name, :string
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ class CreateSemistaticParts < ActiveRecord::Migration
2
+ def change
3
+ create_table :semistatic_parts do |t|
4
+ t.string :name
5
+ t.references :page
6
+ t.text :value
7
+
8
+ # file fields
9
+ t.string :file_file_name
10
+ t.integer :file_file_size
11
+ t.string :file_content_type
12
+ t.datetime :file_updated_at
13
+
14
+ t.timestamps
15
+ end
16
+ add_index :semistatic_parts, :page_id
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ class AddOptionsToParts < ActiveRecord::Migration
2
+ def change
3
+ add_column :semistatic_parts, :options, :text
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddLayoutToPages < ActiveRecord::Migration
2
+ def change
3
+ add_column :semistatic_pages, :layout, :string
4
+ end
5
+ end
@@ -0,0 +1,38 @@
1
+ require "semistatic/engine"
2
+ require 'paperclip'
3
+ require 'tinymce-rails'
4
+
5
+ module Semistatic
6
+
7
+ # configure plugin
8
+ # Usage example:
9
+ # Semistatic.configure do |config|
10
+ # config.template_path = '/path/to/templates'
11
+ # config.config_files = ['/file1.yml','file2.yml']
12
+ # end
13
+ #
14
+ # @param Semistatic::Configuration configuration
15
+ def self.configure(configuration = Semistatic::Configuration.new)
16
+ yield configuration if block_given?
17
+ @@configuration = configuration
18
+ end
19
+
20
+ # get the configuration object
21
+ # @return Semistatic::Configuration.new
22
+ def self.configuration
23
+ @@configuration ||= Semistatic::Configuration.new
24
+ end
25
+
26
+ autoload :Configuration, 'semistatic/configuration'
27
+
28
+ module Concerns
29
+ module Controllers
30
+ autoload :PagesController, 'semistatic/concerns/controllers/pages_controller'
31
+ autoload :PageViewController, 'semistatic/concerns/controllers/page_view_controller'
32
+ end
33
+ end
34
+
35
+ module Presenters
36
+ autoload :PagePresenter, 'semistatic/presenters/page_presenter'
37
+ end
38
+ end
@@ -0,0 +1,30 @@
1
+ module Semistatic
2
+ module Concerns
3
+ module Controllers
4
+ module PageViewController
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ helper_method :semistatic_content
9
+ end
10
+
11
+ # get the page by slug
12
+ # show action
13
+ # render "layouts/templates/#{@page.template_name}"
14
+ # @raises ActiveRecord::RecordNotFound when page is not found
15
+ def show
16
+ page = Page.find_by_slug(params[:slug])
17
+
18
+ unless page
19
+ raise ActiveRecord::RecordNotFound.new("Page not found")
20
+ end
21
+
22
+ @presenter = Presenters::PagePresenter.new(page, self.class.helpers)
23
+
24
+ render file: "semistatic/#{page.template_name}", layout: page.layout
25
+ end
26
+
27
+ end # PageViewController
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,83 @@
1
+ module Semistatic
2
+ module Concerns
3
+ module Controllers
4
+ module PagesController
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ respond_to :html
9
+ before_filter :set_pages_config
10
+ end
11
+
12
+ # GET /pages
13
+ # GET /pages.json
14
+ def index
15
+ @pages = Page.all
16
+ respond_with(@pages)
17
+ end
18
+
19
+ # GET /pages/1
20
+ # GET /pages/1.json
21
+ def show
22
+ @page = find_or_create_page
23
+ @presenter = Presenters::PagePresenter.new(@page, self.class.helpers)
24
+ respond_with(@page)
25
+ end
26
+
27
+ # GET /pages/new
28
+ # GET /pages/new.json
29
+ def new
30
+ redirect_to edit_page_path(find_or_create_page)
31
+ end
32
+
33
+ # GET /pages/1/edit
34
+ def edit
35
+ @page = find_or_create_page
36
+ @presenter = Presenters::PagePresenter.new(@page, self.class.helpers)
37
+ respond_with(@page)
38
+ end
39
+
40
+ # POST /pages
41
+ # POST /pages.json
42
+ def create
43
+ redirect_to pages_path
44
+ end
45
+
46
+ # PUT /pages/1
47
+ # PUT /pages/1.json
48
+ def update
49
+ @page = find_or_create_page
50
+
51
+ unless @page.update_attributes(params[:page])
52
+ @presenter = Presenters::PagePresenter.new(@page, self.class.helpers)
53
+ end
54
+
55
+ respond_with(@page)
56
+ end
57
+
58
+ # DELETE /pages/1
59
+ # DELETE /pages/1.json
60
+ def destroy
61
+ @page = Page.find(params[:id])
62
+ @page.destroy
63
+ respond_with(@page)
64
+ end
65
+
66
+ private
67
+ def set_pages_config
68
+ @config = Semistatic.configuration
69
+ @config.load
70
+ end
71
+
72
+ def find_or_create_page
73
+ if params[:id]
74
+ Page.find(params[:id])
75
+ else
76
+ Page.factory(params[:template_name], @config.page(params[:template_name]))
77
+ end
78
+ end
79
+
80
+ end # PagesController
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,59 @@
1
+ require 'yaml'
2
+
3
+ module Semistatic
4
+ class Configuration
5
+ class Error < StandardError; end
6
+
7
+ def initialize
8
+ @templates_path = Rails.root. + 'app/views/layout'
9
+ @config_files = [(Rails.root. + 'config/semistatic.yml')]
10
+ @config = HashWithIndifferentAccess.new({pages: {}})
11
+ end
12
+
13
+ # set the template path
14
+ # @param Pathname path
15
+ def templates_path=(path)
16
+ @templates_path = path
17
+ end
18
+
19
+ # get the template path
20
+ # @return Pathname
21
+ def templates_path
22
+ @templates_path
23
+ end
24
+
25
+ # set the config files
26
+ # @param Array[Pathname] files # the filepaths in a array
27
+ def config_files=(files)
28
+ @config_files = files
29
+ end
30
+
31
+ # get the config files
32
+ # @return Array # the filepaths in a array
33
+ def config_files
34
+ @config_files
35
+ end
36
+
37
+ # load config from files
38
+ def load
39
+ config_files.each do |file|
40
+ config = YAML::load(File.open(file))
41
+ @config.merge! config
42
+ end
43
+ end
44
+
45
+ # @return Hash
46
+ def pages
47
+ @config[:pages]
48
+ end
49
+
50
+ # @param Symbol key
51
+ # @return hash
52
+ def page(key)
53
+ page = pages[key]
54
+ raise Error.new("There is no page named '#{key}'") unless page
55
+ page
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,11 @@
1
+ module Semistatic
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Semistatic
4
+
5
+ config.generators do |g|
6
+ g.test_framework :rspec
7
+ g.integration_tool :rspec
8
+ g.fixture_replacement :factory_girl, :dir => 'spec/factories'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,79 @@
1
+ module Semistatic
2
+ module Presenters
3
+ class PagePresenter
4
+
5
+ attr_accessor :helpers, :page
6
+
7
+
8
+ def initialize(page, helpers)
9
+ @page = page
10
+ @helpers = helpers
11
+ end
12
+
13
+ # ouput a part
14
+ # @param Symbol name # the part name
15
+ # # when :page_title => page.title
16
+ # # else render the part as with its type renderer
17
+ #
18
+ # @return string
19
+ def output(name)
20
+ if name.to_sym == :page_title
21
+ @page.title
22
+ else
23
+ part = @page.part(name)
24
+ method = "output_#{part.type}"
25
+
26
+ if respond_to?(method)
27
+ send(method, part)
28
+ else
29
+ part.value
30
+ end
31
+ end
32
+ end
33
+
34
+ # render the part as html
35
+ # @param Symbol name # the part name
36
+ # @return String
37
+ def output_html(part)
38
+ helpers.raw part.value
39
+ end
40
+
41
+ # render the part as simple formated text
42
+ # @param Symbol name # the part name
43
+ # @return String
44
+ def output_text(part)
45
+ helpers.simple_format(part.value)
46
+ end
47
+
48
+ # render the part as html
49
+ # @param Symbol name # the part name
50
+ # @param Symbol size # defaults to :original
51
+ # @return String
52
+ def output_image(part, size = :original)
53
+ if part.file?
54
+ helpers.image_tag(part.file.url(size))
55
+ end
56
+ end
57
+
58
+ # @param ActionView::Helpers::FormBuilder form
59
+ # @return String # => the input element for the form
60
+ def input(form)
61
+ part = form.object
62
+ case part.type
63
+ when :string
64
+ form.text_field :value
65
+ when :html
66
+ form.text_area :value, class: 'html wysiwyg tinymce'
67
+ when :text
68
+ form.text_area :value
69
+ when :image
70
+ input = form.file_field :file
71
+ if part.file?
72
+ input = output(part.name) + input
73
+ end
74
+ helpers.content_tag(:div, input)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,3 @@
1
+ module Semistatic
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :semistatic do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,261 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: semistatic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Marcelo Jacobus
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: jquery-rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: tinymce-rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: paperclip
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec-rails
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: shoulda-matchers
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '1.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '1.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: factory_girl_rails
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: database_cleaner
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: guard-rspec
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rb-inotify
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - '>='
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - '>='
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: simplecov
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - '>='
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: coveralls
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - '>='
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - '>='
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ description: Simple embeded page creator. Should I be called CMS? Not sure.
196
+ email:
197
+ - marcelo.jacobus@gmail.com
198
+ executables: []
199
+ extensions: []
200
+ extra_rdoc_files: []
201
+ files:
202
+ - app/assets/javascripts/semistatic/semistatic.js
203
+ - app/assets/javascripts/semistatic/pages.js
204
+ - app/assets/stylesheets/semistatic/pages.css
205
+ - app/assets/stylesheets/semistatic/application.css
206
+ - app/helpers/semistatic/application_helper.rb
207
+ - app/models/semistatic/page.rb
208
+ - app/models/semistatic/part.rb
209
+ - app/views/layouts/semistatic/application.html.erb
210
+ - app/views/semistatic/page_view/show.html.erb
211
+ - app/views/semistatic/pages/edit.html.erb
212
+ - app/views/semistatic/pages/_form.html.erb
213
+ - app/views/semistatic/pages/new.html.erb
214
+ - app/views/semistatic/pages/show.html.erb
215
+ - app/views/semistatic/pages/index.html.erb
216
+ - app/controllers/semistatic/page_view_controller.rb
217
+ - app/controllers/semistatic/pages_controller.rb
218
+ - app/controllers/semistatic/application_controller.rb
219
+ - config/tinymce.yml
220
+ - config/routes.rb
221
+ - db/migrate/20130122165327_create_semistatic_parts.rb
222
+ - db/migrate/20130122144450_add_template_name_to_pages.rb
223
+ - db/migrate/20130123191541_add_options_to_parts.rb
224
+ - db/migrate/20130121193153_create_semistatic_pages.rb
225
+ - db/migrate/20130128113556_add_layout_to_pages.rb
226
+ - lib/semistatic.rb
227
+ - lib/tasks/semistatic_tasks.rake
228
+ - lib/semistatic/engine.rb
229
+ - lib/semistatic/concerns/controllers/page_view_controller.rb
230
+ - lib/semistatic/concerns/controllers/pages_controller.rb
231
+ - lib/semistatic/configuration.rb
232
+ - lib/semistatic/presenters/page_presenter.rb
233
+ - lib/semistatic/version.rb
234
+ - MIT-LICENSE
235
+ - Rakefile
236
+ - README.md
237
+ homepage: https://github.com/mjacobus/semistatic
238
+ licenses:
239
+ - MIT
240
+ metadata: {}
241
+ post_install_message:
242
+ rdoc_options: []
243
+ require_paths:
244
+ - lib
245
+ required_ruby_version: !ruby/object:Gem::Requirement
246
+ requirements:
247
+ - - '>='
248
+ - !ruby/object:Gem::Version
249
+ version: '0'
250
+ required_rubygems_version: !ruby/object:Gem::Requirement
251
+ requirements:
252
+ - - '>='
253
+ - !ruby/object:Gem::Version
254
+ version: '0'
255
+ requirements: []
256
+ rubyforge_project:
257
+ rubygems_version: 2.0.3
258
+ signing_key:
259
+ specification_version: 4
260
+ summary: Simple embeded page creator
261
+ test_files: []