feather_cms 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 (42) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/README.md +46 -0
  4. data/Rakefile +1 -0
  5. data/feather_cms.gemspec +24 -0
  6. data/lib/feather_cms/config.rb +54 -0
  7. data/lib/feather_cms/model.rb +59 -0
  8. data/lib/feather_cms/railtie.rb +13 -0
  9. data/lib/feather_cms/template_cache.rb +52 -0
  10. data/lib/feather_cms/version.rb +3 -0
  11. data/lib/feather_cms/view_helper.rb +20 -0
  12. data/lib/feather_cms.rb +19 -0
  13. data/lib/generators/feather_cms/USAGE +10 -0
  14. data/lib/generators/feather_cms/feather_cms_generator.rb +63 -0
  15. data/lib/generators/feather_cms/templates/bootstrap.css +3992 -0
  16. data/lib/generators/feather_cms/templates/codemirror/codemirror.css +117 -0
  17. data/lib/generators/feather_cms/templates/codemirror/codemirror.js +2909 -0
  18. data/lib/generators/feather_cms/templates/codemirror/feather_cms.js +13 -0
  19. data/lib/generators/feather_cms/templates/codemirror/modes/css.js +124 -0
  20. data/lib/generators/feather_cms/templates/codemirror/modes/htmlmixed.js +83 -0
  21. data/lib/generators/feather_cms/templates/codemirror/modes/javascript.js +360 -0
  22. data/lib/generators/feather_cms/templates/codemirror/modes/xml.js +267 -0
  23. data/lib/generators/feather_cms/templates/codemirror/util/dialog.css +23 -0
  24. data/lib/generators/feather_cms/templates/codemirror/util/dialog.js +63 -0
  25. data/lib/generators/feather_cms/templates/codemirror/util/foldcode.js +186 -0
  26. data/lib/generators/feather_cms/templates/codemirror/util/formatting.js +294 -0
  27. data/lib/generators/feather_cms/templates/codemirror/util/javascript-hint.js +134 -0
  28. data/lib/generators/feather_cms/templates/codemirror/util/match-highlighter.js +44 -0
  29. data/lib/generators/feather_cms/templates/codemirror/util/overlay.js +51 -0
  30. data/lib/generators/feather_cms/templates/codemirror/util/runmode.js +49 -0
  31. data/lib/generators/feather_cms/templates/codemirror/util/search.js +114 -0
  32. data/lib/generators/feather_cms/templates/codemirror/util/searchcursor.js +117 -0
  33. data/lib/generators/feather_cms/templates/codemirror/util/simple-hint.css +16 -0
  34. data/lib/generators/feather_cms/templates/codemirror/util/simple-hint.js +68 -0
  35. data/lib/generators/feather_cms/templates/controller.rb +34 -0
  36. data/lib/generators/feather_cms/templates/form.html.erb +40 -0
  37. data/lib/generators/feather_cms/templates/index.html.erb +11 -0
  38. data/lib/generators/feather_cms/templates/initializer.rb +5 -0
  39. data/lib/generators/feather_cms/templates/layout.html.erb +52 -0
  40. data/lib/generators/feather_cms/templates/migration.rb +13 -0
  41. data/lib/generators/feather_cms/templates/model.rb +3 -0
  42. metadata +98 -0
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in feather_cms.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # Motivation
2
+ We have felt the pain of integrating static pages into a Rails application. There are plenty of gems available for this (Radiant, Locomotiv, etc.) but they are very heavy for what we need.
3
+
4
+ So, we built FeatherCMS. As the name suggests, its a Do-It-Yourself, lightweight CMS - just pages, caching and nothing more!
5
+
6
+ # Usage
7
+ Add the gem to your Gemfile
8
+
9
+ gem 'feather_cms'
10
+
11
+ Now, generate the pages
12
+
13
+ $ rake db:migrate
14
+
15
+ $ rails g feather_cms about_us jobs team
16
+
17
+ This generates a route, the controller action and the view for each page. Start the server and use the URL http://localhost:3000/feathers/pages to go to the admin panel.
18
+
19
+ This has basic HTTP authentication setup.The default username and password are feather/password and you can change this in feathers_controller.rb
20
+
21
+ http_basic_authenticate_with name: 'feather', password: 'password', except: :published
22
+
23
+ # Features
24
+
25
+ * Creates a route for each static page.
26
+ * Caching the static pages.
27
+ * Creates the view in app/views/feathers folder
28
+ * Easily customization FeathersController
29
+ * CodeMirror Editor for syntax highlighting. (Default: HTML)
30
+ * Storage is file (default) or database.
31
+
32
+ # Caveats
33
+ You may need to ensure that the public/system folder exists (for file storage)
34
+
35
+ # TODO
36
+
37
+ * Move the basic authentication to the config/initializers/feather_cms.rb
38
+ * Override the default authentication strategy from the controller
39
+ * Move the code from generated controller to the gem (if required)
40
+
41
+ # Contribute
42
+ Fork away and send me pull requests!
43
+
44
+ # License
45
+ The MIT license
46
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "feather_cms/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "feather_cms"
7
+ s.version = FeatherCms::VERSION
8
+ s.authors = ["Jiren Patel"]
9
+ s.email = ["jiren@joshsoftware.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Lightweight do it youself cms}
12
+ s.description = %q{Lightweight do it youself cms}
13
+
14
+ s.rubyforge_project = "feather_cms"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
@@ -0,0 +1,54 @@
1
+ module FeatherCms
2
+ class Config
3
+ class << self
4
+ attr_accessor :cache_max_limit, :cache_permanent_keys
5
+ attr_accessor :template_store_type
6
+
7
+ @@config = {
8
+ :template_store_path => 'templates',
9
+ :use_version => true,
10
+ :template_extenstion => 'html'
11
+ }
12
+
13
+ def init(&block)
14
+ yield self if block_given?
15
+
16
+ template_store_type = (template_store_type || :file).to_sym
17
+ FeatherCms::TemplateCache.init
18
+ Dir.mkdir(template_store_path) unless Dir.exists?(template_store_path)
19
+
20
+ if defined?(ActionView::Helpers)
21
+ ActionView::Helpers.send(:include, FeatherCms::ViewHelper)
22
+ end
23
+
24
+ if defined?(Rails)
25
+ @@config[:layouts] = Dir.entries(Rails.root.to_s + '/app/views/layouts').reject do |i|
26
+ i.start_with?('.', '_', 'feather_layout')
27
+ end.collect{|l| l.split('.').first}
28
+ end
29
+ end
30
+
31
+ def template_store_path=(value)
32
+ @@config[:template_store_path] = value
33
+ end
34
+
35
+ def template_store_path
36
+ @@config[:template_store_path]
37
+ end
38
+
39
+ def template_extenstion=(value)
40
+ @@config[:template_extenstion] = value
41
+ end
42
+
43
+ def template_extenstion
44
+ @@config[:template_extenstion]
45
+ end
46
+
47
+ def layouts
48
+ @@config[:layouts]
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,59 @@
1
+ module FeatherCms
2
+ module Model
3
+ module ClassMethods
4
+ def template_content_field(name)
5
+ _cms_content_fields_ << name
6
+ return unless Config.template_store_type == :file
7
+
8
+ attr_accessor name.to_sym
9
+
10
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
11
+ def #{name}
12
+ @#{name} || _cms_content(:#{name})
13
+ end
14
+ METHOD
15
+
16
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
17
+ def #{name}_changed?
18
+ @#{name} != _cms_content(:#{name})
19
+ end
20
+ METHOD
21
+ end
22
+
23
+ def _cms_content_fields_
24
+ @_cms_content_fields_ ||= []
25
+ end
26
+
27
+ def define_feather_cms_callbacks
28
+ after_destroy { |template|
29
+ self.class._cms_content_fields_.each do |f|
30
+ TemplateCache.delete_file(_template_path(f))
31
+ end
32
+ }
33
+
34
+ after_save { |template|
35
+ self.class._cms_content_fields_.each do |f|
36
+ TemplateCache.write_to_file_and_cache(send(f), template_name(f))
37
+ end
38
+ }
39
+ end
40
+ end
41
+
42
+ module InstanceMethods
43
+
44
+ def template_name(field_name)
45
+ "#{self.class.name.downcase}_#{field_name}_#{self.id}.#{Config.template_extenstion}"
46
+ end
47
+
48
+ def _template_path(field)
49
+ File.join([Config.template_store_path, template_name(file)])
50
+ end
51
+
52
+ def _cms_content(field)
53
+ return nil if self.id.nil?
54
+ TemplateCache.cache_file(template_name(field))
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,13 @@
1
+ require 'rails'
2
+
3
+ module FeatherCms
4
+ module Railtie
5
+ class Railtie < ::Rails::Railtie
6
+ if ::Rails.version.to_f >= 3.1
7
+ config.before_configuration do |app|
8
+ app.config.assets.paths << Rails.root.join("app", "assets", "codemirror")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,52 @@
1
+ module FeatherCms
2
+ class TemplateCache
3
+ class << self
4
+
5
+ def init(options = {})
6
+ @@_cache ||= {}
7
+ @@options = options
8
+ end
9
+
10
+ def [](key)
11
+ @@_cache[key.to_s]
12
+ end
13
+
14
+ def []=(k,v)
15
+ @@_cache[k.to_s] = v
16
+ end
17
+
18
+ def cache_file(name)
19
+ return self[name] if exist?(name)
20
+
21
+ file = _file_path(name)
22
+ self[file] = File.read(file) if File.exist?(file)
23
+ end
24
+
25
+ def write_to_file_and_cache(content, file)
26
+ return if cache_file(file) == content
27
+ self[file] = content
28
+ File.open(_file_path(file), 'wb') {|f| f.write(content) }
29
+ end
30
+
31
+ def exist?(name)
32
+ @@_cache.key?(name.to_s)
33
+ end
34
+
35
+ def clear(name = nil)
36
+ name ? @@_cache.delete(name.to_s) : @@_cache.clear
37
+ end
38
+
39
+ def delete_file(name)
40
+ file = _file_path(name)
41
+ File.delete(file) if File.exist?(file)
42
+ @@_cache.delete(name)
43
+ end
44
+
45
+ private
46
+ def _file_path(name)
47
+ File.join([Config.template_store_path, name])
48
+ end
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,3 @@
1
+ module FeatherCms
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,20 @@
1
+ module FeatherCms
2
+ module ViewHelper
3
+ def feather_cms_include_tag
4
+ javascript_include_tag('codemirror', 'modes/htmlmixed', 'modes/javascript',
5
+ 'modes/xml', 'modes/css', 'feather_cms') +
6
+ stylesheet_link_tag('codemirror')
7
+ end
8
+
9
+ def feather_cms_template(object_name, method, options = {})
10
+ options[:class] = "#{options[:class]} codemirror_feather_cms"
11
+ text_area(object_name, method, options = {})
12
+ end
13
+
14
+ def feather_cms_template_tag(name, content = nil, options = {})
15
+ options[:class] = "#{options[:class]} codemirror_feather_cms"
16
+ text_area_tag(name, content = nil, options = {})
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ require "feather_cms/version"
2
+ require "feather_cms/template_cache"
3
+ require "feather_cms/config"
4
+ require "feather_cms/model"
5
+ require "feather_cms/view_helper"
6
+ require "feather_cms/railtie" if defined?(Rails)
7
+
8
+ module FeatherCms
9
+ include Model
10
+
11
+ def self.included(base)
12
+ base.extend FeatherCms::Model::ClassMethods
13
+ if Config.template_store_type == :file
14
+ base.define_feather_cms_callbacks
15
+ end
16
+ base.template_content_field :content
17
+ base.send(:include, FeatherCms::Model::InstanceMethods)
18
+ end
19
+ end
@@ -0,0 +1,10 @@
1
+ Description:
2
+ - Feather cms
3
+
4
+
5
+ Example:
6
+ rails generate feather_cms about_us jobs [storage=file or db]
7
+
8
+ This will create:
9
+ - Add config file 'feather_cms.eb'
10
+ - Add Codemirror javascript and css
@@ -0,0 +1,63 @@
1
+ class FeatherCmsGenerator < Rails::Generators::NamedBase
2
+ source_root File.expand_path('../templates', __FILE__)
3
+ argument :attributes, :type => :array, :banner => "about_us jobs"
4
+ argument :name, :type => :string, :default => "feather_cms", :required => false
5
+ argument :storage, :type => :string , :default => 'file'
6
+
7
+ def create_cms_files
8
+ @pages = attributes.collect(&:name)
9
+
10
+ unless ['file', 'db'].include?(storage)
11
+ puts "Valid storaage type are db,file"
12
+ storaage = 'file'
13
+ end
14
+ @storaage = storaage
15
+
16
+ template 'initializer.rb', 'config/initializers/feather_cms.rb'
17
+ template 'controller.rb', 'app/controllers/feathers_controller.rb'
18
+ template 'model.rb', 'app/models/feather_page.rb'
19
+
20
+ migration_file = Dir.glob("db/migrate/[0-9]*_*.rb").grep(/\d+_create_feather_pages.rb$/).first
21
+ migration_number = if migration_file
22
+ migration_file.gsub(/_create_feather_pages.rb|db|migrate|\//, '')
23
+ else
24
+ Time.now.utc.to_s.gsub(/[- :UTC]/, '')
25
+ end
26
+
27
+ template 'migration.rb', "db/migrate/#{migration_number}_create_feather_pages.rb"
28
+
29
+ route %{scope '/feathers' do
30
+ match 'page/:type/(:status)' => 'feathers#page', :as => :feather_page
31
+ get 'pages' => 'feathers#index', :as => :feather_pages
32
+ get 'preivew/:type/(:status)' => 'feathers#preivew', :as => 'feather_page_preview'
33
+ end
34
+ get 'page/:type' => 'feathers#published', :as => 'feather_published_page'}
35
+ end
36
+
37
+ def copy_view_files
38
+ @pages = attributes.collect(&:name)
39
+ base_path = File.join("app/views/feathers")
40
+ #empty_directory base_path
41
+ template 'layout.html.erb', 'app/views/layouts/feather_layout.html.erb'
42
+ template 'index.html.erb', File.join(base_path, 'index.html.erb')
43
+
44
+ @pages.each do |type|
45
+ @type = type
46
+ @path = File.join(base_path, "#{type}.html.erb")
47
+ template 'form.html.erb', @path
48
+ end
49
+ end
50
+
51
+ def add_static_files
52
+ if Rails.version > '3.0.9'
53
+ directory 'codemirror', 'app/assets/codemirror'
54
+ copy_file "bootstrap.css", 'app/assets/stylesheets/bootstrap.css'
55
+ else
56
+ directory 'codemirror', 'public/codemirror'
57
+ copy_file "bootstrap.css", 'public/stylesheets/bootstrap.css'
58
+ end
59
+ end
60
+
61
+
62
+
63
+ end