smithycms 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 (169) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +142 -0
  3. data/Rakefile +27 -0
  4. data/app/assets/images/smithy/logo.png +0 -0
  5. data/app/assets/images/smithy/logo2.png +0 -0
  6. data/app/assets/javascripts/smithy/application.js +13 -0
  7. data/app/assets/javascripts/smithy/assets.js.coffee +35 -0
  8. data/app/assets/javascripts/smithy/guides.js +23 -0
  9. data/app/assets/javascripts/smithy/jquery-ui.min.js +5 -0
  10. data/app/assets/javascripts/smithy/nested_forms.js +55 -0
  11. data/app/assets/javascripts/smithy/page_contents.js +4 -0
  12. data/app/assets/javascripts/smithy/pages.js +41 -0
  13. data/app/assets/javascripts/smithy/settings.js +0 -0
  14. data/app/assets/javascripts/smithy/templates.js +25 -0
  15. data/app/assets/stylesheets/smithy/application.css.scss +29 -0
  16. data/app/assets/stylesheets/smithy/assets.css.scss +3 -0
  17. data/app/assets/stylesheets/smithy/bootstrap_and_overrides.css.scss +12 -0
  18. data/app/assets/stylesheets/smithy/content_blocks.css.scss +2 -0
  19. data/app/assets/stylesheets/smithy/forms.css.scss +3 -0
  20. data/app/assets/stylesheets/smithy/guides.css.scss +5 -0
  21. data/app/assets/stylesheets/smithy/layout.css.scss +113 -0
  22. data/app/assets/stylesheets/smithy/pages.css.scss +35 -0
  23. data/app/assets/stylesheets/smithy/templates.css.scss +14 -0
  24. data/app/controllers/smithy/assets_controller.rb +50 -0
  25. data/app/controllers/smithy/base_controller.rb +14 -0
  26. data/app/controllers/smithy/caches_controller.rb +13 -0
  27. data/app/controllers/smithy/content_blocks_controller.rb +50 -0
  28. data/app/controllers/smithy/content_pieces_controller.rb +97 -0
  29. data/app/controllers/smithy/contents_controller.rb +41 -0
  30. data/app/controllers/smithy/guides_controller.rb +9 -0
  31. data/app/controllers/smithy/images_controller.rb +41 -0
  32. data/app/controllers/smithy/page_contents_controller.rb +90 -0
  33. data/app/controllers/smithy/pages_controller.rb +110 -0
  34. data/app/controllers/smithy/settings_controller.rb +46 -0
  35. data/app/controllers/smithy/sitemap_controller.rb +13 -0
  36. data/app/controllers/smithy/templates_controller.rb +79 -0
  37. data/app/helpers/smithy/application_helper.rb +36 -0
  38. data/app/helpers/smithy/assets_helper.rb +9 -0
  39. data/app/helpers/smithy/pages_helper.rb +12 -0
  40. data/app/helpers/smithy/settings_helper.rb +4 -0
  41. data/app/helpers/smithy/templates_helper.rb +4 -0
  42. data/app/helpers/smithy/upload_helper.rb +110 -0
  43. data/app/models/smithy/asset.rb +64 -0
  44. data/app/models/smithy/content.rb +35 -0
  45. data/app/models/smithy/content_block.rb +41 -0
  46. data/app/models/smithy/content_block_template.rb +26 -0
  47. data/app/models/smithy/image.rb +41 -0
  48. data/app/models/smithy/page.rb +94 -0
  49. data/app/models/smithy/page_content.rb +62 -0
  50. data/app/models/smithy/page_list.rb +61 -0
  51. data/app/models/smithy/page_proxy.rb +63 -0
  52. data/app/models/smithy/setting.rb +6 -0
  53. data/app/models/smithy/site.rb +30 -0
  54. data/app/models/smithy/template.rb +53 -0
  55. data/app/models/smithy/template_container.rb +16 -0
  56. data/app/views/layouts/smithy/application.html.erb +27 -0
  57. data/app/views/layouts/smithy/guides.html.erb +16 -0
  58. data/app/views/layouts/smithy/modal.html.erb +10 -0
  59. data/app/views/layouts/smithy/shared/_flash.html.erb +6 -0
  60. data/app/views/layouts/smithy/shared/_footer.html.erb +3 -0
  61. data/app/views/layouts/smithy/shared/_head.html.erb +8 -0
  62. data/app/views/layouts/smithy/shared/_nav.html.erb +37 -0
  63. data/app/views/layouts/smithy/shared/_tail.html.erb +4 -0
  64. data/app/views/layouts/smithy/wide.html.erb +24 -0
  65. data/app/views/smithy/assets/_asset.html.erb +10 -0
  66. data/app/views/smithy/assets/_form.html.erb +13 -0
  67. data/app/views/smithy/assets/_upload_form.html.erb +13 -0
  68. data/app/views/smithy/assets/create.js.erb +5 -0
  69. data/app/views/smithy/assets/edit.html.erb +5 -0
  70. data/app/views/smithy/assets/index.html.erb +13 -0
  71. data/app/views/smithy/assets/new.html.erb +13 -0
  72. data/app/views/smithy/caches/show.html.erb +8 -0
  73. data/app/views/smithy/content_blocks/_content_block.html.erb +1 -0
  74. data/app/views/smithy/content_blocks/_secondary_nav.html.erb +12 -0
  75. data/app/views/smithy/content_blocks/_template_fields.html.erb +19 -0
  76. data/app/views/smithy/content_blocks/edit.html.erb +31 -0
  77. data/app/views/smithy/content_blocks/index.html.erb +17 -0
  78. data/app/views/smithy/content_blocks/new.html.erb +12 -0
  79. data/app/views/smithy/content_pieces/edit.html.erb +13 -0
  80. data/app/views/smithy/content_pieces/index.html.erb +21 -0
  81. data/app/views/smithy/content_pieces/new.html.erb +1 -0
  82. data/app/views/smithy/contents/_form.html.erb +6 -0
  83. data/app/views/smithy/contents/_form_fields.html.erb +12 -0
  84. data/app/views/smithy/contents/edit.html.erb +3 -0
  85. data/app/views/smithy/contents/new.html.erb +3 -0
  86. data/app/views/smithy/guides/markdown.html.erb +150 -0
  87. data/app/views/smithy/images/_form.html.erb +6 -0
  88. data/app/views/smithy/images/_form_fields.html.erb +28 -0
  89. data/app/views/smithy/images/edit.html.erb +3 -0
  90. data/app/views/smithy/images/new.html.erb +3 -0
  91. data/app/views/smithy/page_contents/edit.html.erb +18 -0
  92. data/app/views/smithy/page_contents/new.html.erb +28 -0
  93. data/app/views/smithy/page_lists/_form_fields.html.erb +6 -0
  94. data/app/views/smithy/pages/_container.html.erb +24 -0
  95. data/app/views/smithy/pages/_form.html.erb +57 -0
  96. data/app/views/smithy/pages/_page.html.erb +6 -0
  97. data/app/views/smithy/pages/_page_nav.html.erb +6 -0
  98. data/app/views/smithy/pages/_page_related.html.erb +21 -0
  99. data/app/views/smithy/pages/_parent.html.erb +10 -0
  100. data/app/views/smithy/pages/_root.html.erb +5 -0
  101. data/app/views/smithy/pages/edit.html.erb +7 -0
  102. data/app/views/smithy/pages/index.html.erb +17 -0
  103. data/app/views/smithy/pages/new.html.erb +7 -0
  104. data/app/views/smithy/settings/_form.html.erb +7 -0
  105. data/app/views/smithy/settings/_setting.html.erb +6 -0
  106. data/app/views/smithy/settings/edit.html.erb +3 -0
  107. data/app/views/smithy/settings/index.html.erb +9 -0
  108. data/app/views/smithy/settings/new.html.erb +3 -0
  109. data/app/views/smithy/settings/show.html.erb +10 -0
  110. data/app/views/smithy/sitemap/show.xml.erb +10 -0
  111. data/app/views/smithy/templates/_secondary_nav.html.erb +21 -0
  112. data/app/views/smithy/templates/_template.html.erb +1 -0
  113. data/app/views/smithy/templates/edit.html.erb +36 -0
  114. data/app/views/smithy/templates/index.html.erb +17 -0
  115. data/app/views/smithy/templates/new.html.erb +13 -0
  116. data/config/initializers/aws.rb +5 -0
  117. data/config/initializers/dragonfly.rb +48 -0
  118. data/config/initializers/formtastic.rb +77 -0
  119. data/config/initializers/kaminari_config.rb +10 -0
  120. data/config/initializers/liquid.rb +2 -0
  121. data/config/routes.rb +38 -0
  122. data/db/migrate/20120911193140_create_smithy_templates.rb +11 -0
  123. data/db/migrate/20120911203618_create_smithy_settings.rb +10 -0
  124. data/db/migrate/20121018182146_create_smithy_pages.rb +27 -0
  125. data/db/migrate/20121019145543_create_smithy_template_containers.rb +11 -0
  126. data/db/migrate/20121019160426_create_smithy_page_contents.rb +21 -0
  127. data/db/migrate/20121024213357_create_smithy_content_blocks.rb +10 -0
  128. data/db/migrate/20121025011733_create_smithy_content_block_templates.rb +12 -0
  129. data/db/migrate/20121029175812_create_smithy_contents.rb +9 -0
  130. data/db/migrate/20121105222537_create_smithy_assets.rb +16 -0
  131. data/db/migrate/20121115215053_create_smithy_images.rb +15 -0
  132. data/db/migrate/20121127205022_add_external_link_to_smithy_pages.rb +5 -0
  133. data/db/migrate/20130115190505_add_markdown_content_to_smithy_contents.rb +5 -0
  134. data/db/migrate/20130123170918_set_defaults_for_show_in_navigation_and_cache_length.rb +6 -0
  135. data/db/migrate/20130311203806_create_smithy_page_lists.rb +15 -0
  136. data/db/migrate/20130312161116_remove_description_from_content_block.rb +5 -0
  137. data/db/migrate/20130326191051_add_html_attributes_to_images.rb +5 -0
  138. data/db/migrate/20131003210228_add_publishable_to_smithy_page_contents.rb +11 -0
  139. data/db/migrate/20131220160755_add_content_to_images.rb +5 -0
  140. data/db/migrate/20131223145710_add_position_to_smithy_template_containers.rb +5 -0
  141. data/lib/smithy/content_blocks/model.rb +16 -0
  142. data/lib/smithy/content_blocks/registry.rb +30 -0
  143. data/lib/smithy/content_blocks.rb +2 -0
  144. data/lib/smithy/content_pieces/base.rb +10 -0
  145. data/lib/smithy/content_pieces/registry.rb +39 -0
  146. data/lib/smithy/dependencies.rb +19 -0
  147. data/lib/smithy/dragonfly/asset_helper.rb +67 -0
  148. data/lib/smithy/dragonfly/remote_data_store.rb +33 -0
  149. data/lib/smithy/dragonfly.rb +30 -0
  150. data/lib/smithy/engine.rb +48 -0
  151. data/lib/smithy/formatter.rb +46 -0
  152. data/lib/smithy/liquid/database.rb +12 -0
  153. data/lib/smithy/liquid/drops/base.rb +16 -0
  154. data/lib/smithy/liquid/drops/page.rb +78 -0
  155. data/lib/smithy/liquid/filters/asset_tag.rb +33 -0
  156. data/lib/smithy/liquid/filters/resize.rb +12 -0
  157. data/lib/smithy/liquid/rendering.rb +50 -0
  158. data/lib/smithy/liquid/tags/asset.rb +54 -0
  159. data/lib/smithy/liquid/tags/csrf.rb +30 -0
  160. data/lib/smithy/liquid/tags/html.rb +61 -0
  161. data/lib/smithy/liquid/tags/nav.rb +76 -0
  162. data/lib/smithy/liquid.rb +8 -0
  163. data/lib/smithy/logger.rb +12 -0
  164. data/lib/smithy/version.rb +3 -0
  165. data/lib/smithy.rb +21 -0
  166. data/lib/smithycms.rb +1 -0
  167. data/lib/tasks/smithy_tasks.rake +4 -0
  168. data/lib/templates/erb/scaffold/_form.html.erb +11 -0
  169. metadata +871 -0
@@ -0,0 +1,19 @@
1
+ require 'rack/cache'
2
+
3
+ require 'awesome_nested_set'
4
+ require 'bootstrap-sass'
5
+ require 'awesome_nested_set'
6
+ require 'dragonfly'
7
+ require 'fog'
8
+ require 'font-awesome-sass-rails'
9
+ require 'formtastic'
10
+ require 'formtastic-bootstrap'
11
+ require 'friendly_id'
12
+ require 'httparty'
13
+ require 'kaminari'
14
+ require 'jquery-fileupload-rails'
15
+ require 'jquery/rails'
16
+ require 'liquid'
17
+ require 'sass-rails'
18
+ require 'slodown'
19
+
@@ -0,0 +1,67 @@
1
+ module Smithy
2
+ module Dragonfly
3
+ module AssetHelper
4
+
5
+ extend ActiveSupport::Concern
6
+ included do
7
+ before_save :set_content_types
8
+ end
9
+
10
+ module ClassMethods
11
+ def content_types
12
+ {
13
+ :image => ['image/jpeg', 'image/pjpeg', 'image/gif', 'image/png', 'image/x-png', 'image/jpg', 'image/x-icon'],
14
+ :media => [/^video/, 'application/x-shockwave-flash', 'application/x-flash-video', 'application/x-swf', /^audio/, 'application/ogg', 'application/x-mp3'],
15
+ :pdf => ['application/pdf', 'application/x-pdf'],
16
+ :stylesheet => ['text/css'],
17
+ :javascript => ['text/javascript', 'text/js', 'application/x-javascript', 'application/javascript', 'text/x-component'],
18
+ :font => ['application/x-font-ttf', 'application/vnd.ms-fontobject', 'image/svg+xml', 'application/x-woff']
19
+ }
20
+ end
21
+
22
+ def dragonfly_datastore
23
+ if ENV['AWS_ACCESS_KEY_ID'].present? && ENV['AWS_SECRET_ACCESS_KEY'].present? && ENV['AWS_S3_BUCKET'].present?
24
+ datastore = ::Dragonfly::DataStorage::S3DataStore.new
25
+ datastore.configure do |c|
26
+ c.bucket_name = ENV['AWS_S3_BUCKET']
27
+ c.access_key_id = ENV['AWS_ACCESS_KEY_ID']
28
+ c.secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
29
+ # c.region = 'eu-west-1' # defaults to 'us-east-1'
30
+ # c.storage_headers = {'some' => 'thing'} # defaults to {'x-amz-acl' => 'public-read'}
31
+ # c.url_scheme = 'https' # defaults to 'http'
32
+ # c.url_host = 'some.custom.host' # defaults to "<bucket_name>.s3.amazonaws.com"
33
+ end
34
+ else
35
+ datastore = ::Dragonfly::DataStorage::FileDataStore.new
36
+ end
37
+ datastore
38
+ end
39
+
40
+ def dragonfly_remote_datastore
41
+ ::Smithy::Dragonfly::DataStorage::RemoteDataStore.new
42
+ end
43
+
44
+ end
45
+
46
+ def set_content_types
47
+ # empty by default - override in your own models if you need to use it
48
+ end
49
+
50
+ def set_content_type(file, content_type_column)
51
+ return unless file.present?
52
+ value = :other
53
+ content_type = file.mime_type
54
+ self.class.content_types.each_pair do |type, rules|
55
+ rules.each do |rule|
56
+ case rule
57
+ when String then value = type if content_type == rule
58
+ when Regexp then value = type if (content_type =~ rule) == 0
59
+ end
60
+ end
61
+ end
62
+ self[content_type_column] = value.to_s
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,33 @@
1
+ require 'httparty'
2
+ module Smithy
3
+ module Dragonfly
4
+ module DataStorage
5
+ class RemoteDataStore
6
+ include ::Dragonfly::Configurable
7
+
8
+ def store(temp_object, opts={})
9
+ # raise "Sorry friend, this datastore is read-only."
10
+ end
11
+
12
+ def retrieve(uid)
13
+ response = HTTParty.get uid, :timeout => 3
14
+ unless response.ok?
15
+ #raise Forbidden if response.code == 403
16
+ raise DataNotFound
17
+ end
18
+
19
+ content = response.body
20
+ extra_data = {}
21
+ [
22
+ content, # either a File, String or Tempfile
23
+ extra_data # Hash with optional keys :meta, :name, :format
24
+ ]
25
+ end
26
+
27
+ def destroy(uid)
28
+ raise "Sorry friend, this datastore is read-only."
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,30 @@
1
+ require 'smithy/dragonfly/asset_helper'
2
+ require 'smithy/dragonfly/remote_data_store'
3
+ module Smithy
4
+ module Dragonfly
5
+
6
+ def self.resize_url(source, resize_string)
7
+ file = nil
8
+
9
+ if source.is_a?(String)
10
+ source.strip!
11
+ if source =~ /^http/
12
+ file = self.app.fetch_url(source)
13
+ else
14
+ file = self.app.fetch_file(File.join('public', source))
15
+ end
16
+ elsif source.respond_to?(:url) # dragonfly uploader
17
+ file = source
18
+ else
19
+ Smithy.log :error, "Unable to resize on the fly: #{source.inspect}"
20
+ return
21
+ end
22
+ file.process(:thumb, resize_string).url
23
+ end
24
+
25
+ def self.app
26
+ ::Dragonfly[:files]
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,48 @@
1
+ module Smithy
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Smithy
4
+
5
+ class << self
6
+ attr_accessor :root
7
+ def root
8
+ @root ||= Pathname.new(File.expand_path('../../', File.dirname(__FILE__)))
9
+ end
10
+ end
11
+
12
+ config.autoload_paths += %W(#{config.root}/lib)
13
+
14
+ config.to_prepare do
15
+ # include the Smithy helpers in the host application
16
+ ::ApplicationController.send :helper, Smithy::Engine.helpers
17
+ end
18
+
19
+ config.generators do |g|
20
+ g.test_framework :rspec, :fixture => false, :view_specs => false
21
+ g.integration_tool :rspec
22
+ g.fixture_replacement :factory_girl, :dir => 'spec/factories'
23
+ g.assets false
24
+ g.helper false
25
+ end
26
+
27
+ config.after_initialize do
28
+ # We need to reload the routes here due to how Smithy sets them up.
29
+ # The different facets of Smithy (auth) append/prepend routes to Smithy
30
+ # *after* the main engine has been loaded.
31
+ #
32
+ # So we wait until after initialization is complete to do one final reload.
33
+ # This then makes the appended/prepended routes available to the application.
34
+ Rails.application.routes_reloader.reload!
35
+ # we need to require all our model files so that ContentBlocks
36
+ # are registered with the engine
37
+ Dir[Smithy::Engine.root.join('app', 'models', 'smithy', '*.rb')].each do |file|
38
+ require_dependency file if ActiveRecord::Base.connection.table_exists?(file.pluralize)
39
+ end
40
+ end
41
+
42
+ # TODO: Abstract out the configuration
43
+ # initializer "smithy.config", :before => :load_config_initializers do |app|
44
+ # Smithy::Config = app.config.smithy.preferences
45
+ # end
46
+
47
+ end
48
+ end
@@ -0,0 +1,46 @@
1
+ module Smithy
2
+ class Formatter < ::Slodown::Formatter
3
+
4
+ def render
5
+ self.complete.to_s
6
+ end
7
+
8
+ private
9
+ def kramdown_options
10
+ { coderay_css: 'style' }
11
+ end
12
+
13
+ def sanitize_config
14
+ {
15
+ elements: %w(
16
+ p br a span sub sup strong em div hr abbr
17
+ ul ol li
18
+ blockquote pre code
19
+ h1 h2 h3 h4 h5 h6
20
+ img object param del
21
+ ),
22
+ attributes: {
23
+ :all => ['class', 'style', 'title', 'id'],
24
+ 'a' => ['href', 'rel', 'name', 'target'],
25
+ 'li' => ['id'],
26
+ 'sup' => ['id'],
27
+ 'img' => ['src', 'title', 'alt', 'width', 'height'],
28
+ 'object' => ['width', 'height'],
29
+ 'param' => ['name', 'value'],
30
+ 'embed' => ['allowscriptaccess', 'width', 'height', 'src'],
31
+ 'iframe' => ['width', 'height', 'src']
32
+ },
33
+ protocols: {
34
+ 'a' => { 'href' => ['ftp', 'http', 'https', 'mailto', '#fn', '#fnref', :relative] },
35
+ 'img' => {'src' => ['http', 'https', :relative]},
36
+ 'iframe' => {'src' => ['http', 'https']},
37
+ 'embed' => {'src' => ['http', 'https']},
38
+ 'object' => {'src' => ['http', 'https']},
39
+ 'li' => {'id' => ['fn']},
40
+ 'sup' => {'id' => ['fnref']}
41
+ },
42
+ transformers: ::Slodown::EmbedTransformer
43
+ }
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,12 @@
1
+ module Smithy
2
+ module Liquid
3
+ class Database
4
+ def read_template_file(template_path, context)
5
+ _include = Smithy::Template.partials.where(:name => template_path).first
6
+ raise ActiveRecord::RecordNotFound, "No such template '#{template_path}'" unless _include.present?
7
+
8
+ _include.content
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module Smithy
2
+ module Liquid
3
+ module Drops
4
+ class Base < ::Liquid::Drop
5
+ attr_reader :_source
6
+ def initialize(source)
7
+ @_source = source
8
+ end
9
+
10
+ def id
11
+ (@_source.respond_to?(:id) ? @_source.id : nil) || 'new'
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,78 @@
1
+ module Smithy
2
+ module Liquid
3
+ module Drops
4
+ class Page < Base
5
+ delegate :title, :depth, :permalink, :root, :site, :to => '_source'
6
+
7
+ def breadcrumbs
8
+ self._source.ancestors.where(["id != ?", root]).map(&:to_liquid)
9
+ end
10
+
11
+ def browser_title
12
+ self._source.browser_title.present? ? self._source.browser_title : self.generated_browser_title
13
+ end
14
+
15
+ def children
16
+ self._source.children.map(&:to_liquid)
17
+ end
18
+
19
+ def container
20
+ self.rendered_containers
21
+ end
22
+
23
+ def meta_description
24
+ self._source.description
25
+ end
26
+
27
+ def meta_keywords
28
+ self._source.keywords
29
+ end
30
+
31
+ def parent
32
+ self._source.parent.to_liquid
33
+ end
34
+
35
+ def path
36
+ self._source.url
37
+ end
38
+
39
+ def published?
40
+ self._source.published?
41
+ end
42
+
43
+ def show_in_navigation?
44
+ self._source.show_in_navigation?
45
+ end
46
+
47
+ def root?
48
+ self._source.root?
49
+ end
50
+
51
+ def leaf?
52
+ self._source.leaf?
53
+ end
54
+
55
+ def child?
56
+ self._source.child?
57
+ end
58
+
59
+ protected
60
+ def generated_browser_title
61
+ @generated_browser_title ||= generated_browser_titles.join(' | ')
62
+ end
63
+
64
+ def rendered_containers
65
+ Hash[ *_source.containers.map(&:name).map{|cn| [cn, _source.render_container(cn) ] }.flatten ]
66
+ end
67
+
68
+ private
69
+ def generated_browser_titles
70
+ titles = _source.self_and_ancestors.map(&:title)
71
+ titles.shift unless _source.root? # keep all except the first element unless root
72
+ titles << site.title if site.title.present?
73
+ titles
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,33 @@
1
+ module Smithy
2
+ module Liquid
3
+ module Filters
4
+ module AssetTag
5
+ def image_tag(input, *args)
6
+ image_options = inline_options(args_to_options(args))
7
+ "<img src=\"#{input}\" #{image_options}>"
8
+ end
9
+
10
+ protected
11
+ # Convert an array of properties ('key:value') into a hash
12
+ # Ex: ['width:50', 'height:100'] => { :width => '50', :height => '100' }
13
+ def args_to_options(*args)
14
+ options = {}
15
+ args.flatten.each do |a|
16
+ if (a =~ /^(.*):(.*)$/)
17
+ options[$1.to_sym] = $2
18
+ end
19
+ end
20
+ options
21
+ end
22
+
23
+ # Write options (Hash) into a string according to the following pattern:
24
+ # <key1>="<value1>", <key2>="<value2", ...etc
25
+ def inline_options(options = {})
26
+ return '' if options.empty?
27
+ (options.stringify_keys.sort.to_a.collect { |a, b| "#{a}=\"#{b}\"" }).join(' ') << ' '
28
+ end
29
+ end
30
+ ::Liquid::Template.register_filter(AssetTag)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,12 @@
1
+ module Smithy
2
+ module Liquid
3
+ module Filters
4
+ module Resize
5
+ def resize(input, resize_string)
6
+ Locomotive::Dragonfly.resize_url(input, resize_string)
7
+ end
8
+ end
9
+ ::Liquid::Template.register_filter(Resize)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,50 @@
1
+ module Smithy
2
+ module Liquid
3
+ module Rendering
4
+
5
+ private
6
+
7
+ def render_smithy_page
8
+ if smithy_current_user
9
+ output = @page.template.liquid_template.render(liquid_context)
10
+ else
11
+ output = Rails.cache.fetch("#{@page.cache_key}-render_smithy_page") do
12
+ @page.template.liquid_template.render(liquid_context)
13
+ end
14
+ end
15
+ render :text => output, :layout => false
16
+ end
17
+
18
+ def render_as_smithy_page(template_name)
19
+ output = Smithy::Template.templates.find_by_name(template_name).liquid_template.render(liquid_context)
20
+ render :text => output, :layout => false
21
+ end
22
+
23
+ def liquid_context
24
+ ::Liquid::Context.new({}, smithy_default_assigns, smithy_default_registers, false)
25
+ end
26
+
27
+ def smithy_default_assigns
28
+ {
29
+ 'page' => @page,
30
+ 'current_page' => self.params[:path],
31
+ 'params' => self.params,
32
+ 'path' => request.path,
33
+ 'fullpath' => request.fullpath,
34
+ 'url' => request.url,
35
+ 'now' => Time.now.utc,
36
+ 'today' => Date.today,
37
+ 'site' => @page.site
38
+ }
39
+ end
40
+
41
+ def smithy_default_registers
42
+ {
43
+ :controller => self,
44
+ :page => @page,
45
+ :site => @page.site
46
+ }
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,54 @@
1
+ module Smithy
2
+ module Liquid
3
+ module Tags
4
+ module Asset
5
+ class AssetImageTag < ::Liquid::Tag
6
+ Syntax = /(#{::Liquid::Expression}+)?/
7
+ def initialize(tag_name, markup, tokens)
8
+ if markup =~ Syntax
9
+ @asset_id = $1.gsub('\'', '').strip
10
+ if @asset = ::Smithy::Asset.find_by_id(@asset_id)
11
+ @url = @asset.file.url
12
+ @alt = @asset.name
13
+ else
14
+ @url = @asset_id
15
+ @alt = ''
16
+ end
17
+ else
18
+ raise ::Liquid::SyntaxError.new("Syntax Error in '#{@tag_name}' - Valid syntax: image_tag <asset_id|path>")
19
+ end
20
+ super
21
+ end
22
+
23
+ def render(context)
24
+ controller = context.registers[:controller]
25
+ controller.view_context.send(:image_tag, @url, :alt => @alt)
26
+ end
27
+ end
28
+ class AssetFilePath < ::Liquid::Tag
29
+ Syntax = /(#{::Liquid::Expression}+)?/
30
+ def initialize(tag_name, markup, tokens)
31
+ if markup =~ Syntax
32
+ @asset_id = $1.gsub('\'', '')
33
+ if @asset = ::Smithy::Asset.find_by_id(@asset_id)
34
+ @url = @asset.file.url
35
+ else
36
+ @url = @asset_id
37
+ end
38
+ else
39
+ raise ::Liquid::SyntaxError.new("Syntax Error in '#{@tag_name}' - Valid syntax: file_path <asset_id|path>")
40
+ end
41
+ super
42
+ end
43
+
44
+ def render(context)
45
+ @url
46
+ end
47
+ end
48
+ end
49
+ ::Liquid::Template.register_tag('asset_image_tag', Asset::AssetImageTag)
50
+ ::Liquid::Template.register_tag('asset_image_path', Asset::AssetFilePath)
51
+ ::Liquid::Template.register_tag('asset_file_path', Asset::AssetFilePath)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,30 @@
1
+ module Smithy
2
+ module Liquid
3
+ module Tags
4
+ module Csrf
5
+
6
+ class Param < ::Liquid::Tag
7
+ def render(context)
8
+ controller = context.registers[:controller]
9
+ name = controller.send(:request_forgery_protection_token).to_s
10
+ value = controller.send(:form_authenticity_token)
11
+ %(<input type="hidden" name="#{name}" value="#{value}">)
12
+ end
13
+ end
14
+
15
+ class Meta < ::Liquid::Tag
16
+ def render(context)
17
+ controller = context.registers[:controller]
18
+ name = controller.send(:request_forgery_protection_token).to_s
19
+ value = controller.send(:form_authenticity_token)
20
+ %{<meta name="csrf-param" content="#{name}">\n} +
21
+ %{<meta name="csrf-token" content="#{value}">}
22
+ end
23
+ end
24
+ end
25
+ ::Liquid::Template.register_tag('csrf_param', Csrf::Param)
26
+ ::Liquid::Template.register_tag('csrf_meta_tag', Csrf::Meta)
27
+ ::Liquid::Template.register_tag('csrf_meta_tags', Csrf::Meta)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,61 @@
1
+
2
+ module Smithy
3
+ module Liquid
4
+ module Tags
5
+ module Html
6
+ class Base < ::Liquid::Tag
7
+ Syntax = /(#{::Liquid::Expression}+)?/
8
+ def initialize(tag_name, markup, tokens)
9
+ if markup =~ Syntax
10
+ @tag = $1.gsub('\'', '')
11
+ else
12
+ raise ::Liquid::SyntaxError.new("Syntax Error in '#{tag_name}' - Valid syntax: #{tag_name} <path_to/your_file>")
13
+ end
14
+ super
15
+ end
16
+
17
+ def tag
18
+ @tag
19
+ end
20
+
21
+ def tag_with_ext(ext)
22
+ tag.match(/\.#{ext}$/) ? tag : "#{tag}.#{ext}"
23
+ end
24
+
25
+ def render(context)
26
+ raise Error.new("please override Smithy::Liquid::Tag::Html::Base#render")
27
+ end
28
+ end
29
+
30
+ class StylesheetLinkTag < Base
31
+ def render(context)
32
+ controller = context.registers[:controller]
33
+ controller.view_context.send(:stylesheet_link_tag, tag)
34
+ end
35
+ end
36
+ class JavascriptIncludeTag < Base
37
+ def render(context)
38
+ controller = context.registers[:controller]
39
+ controller.view_context.send(:javascript_include_tag, tag)
40
+ end
41
+ end
42
+ class SmithyJavascriptIncludeTag < Base
43
+ def render(context)
44
+ controller = context.registers[:controller]
45
+ controller.view_context.send(:javascript_include_tag, "/templates/javascripts/#{tag_with_ext('js')}")
46
+ end
47
+ end
48
+ class SmithyStylesheetLinkTag < Base
49
+ def render(context)
50
+ controller = context.registers[:controller]
51
+ controller.view_context.send(:stylesheet_link_tag, "/templates/stylesheets/#{tag_with_ext('css')}")
52
+ end
53
+ end
54
+ end
55
+ ::Liquid::Template.register_tag('stylesheet_link_tag', Html::StylesheetLinkTag)
56
+ ::Liquid::Template.register_tag('javascript_include_tag', Html::JavascriptIncludeTag)
57
+ ::Liquid::Template.register_tag('smithy_javascript_include_tag', Html::SmithyJavascriptIncludeTag)
58
+ ::Liquid::Template.register_tag('smithy_stylesheet_link_tag', Html::SmithyStylesheetLinkTag)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,76 @@
1
+ module Smithy
2
+ module Liquid
3
+ module Tags
4
+ class Nav < ::Liquid::Tag
5
+ Syntax = /(#{::Liquid::Expression}+)?/
6
+
7
+ # {% nav site|page, id: 'main-nav', depth: 1, class: 'nav', active_class: 'on' }
8
+ def initialize(tag_name, markup, tokens)
9
+ @options = { :id => 'nav', :depth => 1, :class => '', :active_class => 'on' }
10
+ if markup =~ Syntax
11
+ @source = ($1 || 'site').gsub(/"|'/, '')
12
+ markup.scan(::Liquid::TagAttributes) do |key, value|
13
+ @options[key.to_sym] = value.gsub(/"|'/, '')
14
+ end
15
+ @options[:depth] = @options[:depth].to_i
16
+ @options[:depth] = 100 if @options[:depth] == 0
17
+ @options[:wrapper] == "false" ? false : true
18
+ else
19
+ raise ::Liquid::SyntaxError.new("Syntax Error in 'nav' - Valid syntax: nav <site|page|section> <options>")
20
+ end
21
+ super
22
+ end
23
+
24
+ def parse(tokens)
25
+ @tokens = tokens
26
+ end
27
+
28
+ def render(context)
29
+ @site = context.registers[:site]
30
+ @page = context.registers[:page]
31
+ @controller = context.registers[:controller]
32
+ render_wrapper(render_list_items(root_node, 1), @options[:id])
33
+ end
34
+
35
+ def render_children(parent, depth)
36
+ list_items = render_list_items(parent, depth)
37
+ return unless list_items.present?
38
+ render_wrapper(list_items)
39
+ end
40
+
41
+ def render_list_item(item, depth)
42
+ item_id = "#{@options[:id]}-#{item.permalink}"
43
+ href = item.url
44
+ label = item.title
45
+ css_class = " class=\"#{@options[:active_class]}\"" if (@page && @page.id == item.id) || (@controller && [item.path, item.external_link].include?(@controller.request.path))
46
+ %Q{#{" " * depth}<li id="#{item_id}"#{css_class}><a href="#{href}" id="#{item_id}-link">#{label}</a>#{render_children(item, depth.succ)}</li>}
47
+ end
48
+
49
+ def render_list_items(parent, depth)
50
+ return if depth > @options[:depth] || parent.leaf?
51
+ parent.children.included_in_navigation.inject([]) do |items, item|
52
+ items << render_list_item(item, depth)
53
+ end.join("\n")
54
+ end
55
+
56
+ def render_wrapper(list_items, id = nil)
57
+ list_id = id.present? ? " id=\"#{id}\"" : ''
58
+ %Q{<ul#{list_id}>\n#{list_items}\n</ul>}
59
+ end
60
+
61
+ def root_node
62
+ case @source
63
+ when 'site'
64
+ Smithy::Page.root
65
+ when 'page'
66
+ @page
67
+ when 'section'
68
+ @page == Smithy::Page.root ? @page : @page.self_and_ancestors.second
69
+ end
70
+ end
71
+
72
+ end
73
+ ::Liquid::Template.register_tag('nav', Nav)
74
+ end
75
+ end
76
+ end