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.
- data/MIT-LICENSE +20 -0
- data/README.md +142 -0
- data/Rakefile +27 -0
- data/app/assets/images/smithy/logo.png +0 -0
- data/app/assets/images/smithy/logo2.png +0 -0
- data/app/assets/javascripts/smithy/application.js +13 -0
- data/app/assets/javascripts/smithy/assets.js.coffee +35 -0
- data/app/assets/javascripts/smithy/guides.js +23 -0
- data/app/assets/javascripts/smithy/jquery-ui.min.js +5 -0
- data/app/assets/javascripts/smithy/nested_forms.js +55 -0
- data/app/assets/javascripts/smithy/page_contents.js +4 -0
- data/app/assets/javascripts/smithy/pages.js +41 -0
- data/app/assets/javascripts/smithy/settings.js +0 -0
- data/app/assets/javascripts/smithy/templates.js +25 -0
- data/app/assets/stylesheets/smithy/application.css.scss +29 -0
- data/app/assets/stylesheets/smithy/assets.css.scss +3 -0
- data/app/assets/stylesheets/smithy/bootstrap_and_overrides.css.scss +12 -0
- data/app/assets/stylesheets/smithy/content_blocks.css.scss +2 -0
- data/app/assets/stylesheets/smithy/forms.css.scss +3 -0
- data/app/assets/stylesheets/smithy/guides.css.scss +5 -0
- data/app/assets/stylesheets/smithy/layout.css.scss +113 -0
- data/app/assets/stylesheets/smithy/pages.css.scss +35 -0
- data/app/assets/stylesheets/smithy/templates.css.scss +14 -0
- data/app/controllers/smithy/assets_controller.rb +50 -0
- data/app/controllers/smithy/base_controller.rb +14 -0
- data/app/controllers/smithy/caches_controller.rb +13 -0
- data/app/controllers/smithy/content_blocks_controller.rb +50 -0
- data/app/controllers/smithy/content_pieces_controller.rb +97 -0
- data/app/controllers/smithy/contents_controller.rb +41 -0
- data/app/controllers/smithy/guides_controller.rb +9 -0
- data/app/controllers/smithy/images_controller.rb +41 -0
- data/app/controllers/smithy/page_contents_controller.rb +90 -0
- data/app/controllers/smithy/pages_controller.rb +110 -0
- data/app/controllers/smithy/settings_controller.rb +46 -0
- data/app/controllers/smithy/sitemap_controller.rb +13 -0
- data/app/controllers/smithy/templates_controller.rb +79 -0
- data/app/helpers/smithy/application_helper.rb +36 -0
- data/app/helpers/smithy/assets_helper.rb +9 -0
- data/app/helpers/smithy/pages_helper.rb +12 -0
- data/app/helpers/smithy/settings_helper.rb +4 -0
- data/app/helpers/smithy/templates_helper.rb +4 -0
- data/app/helpers/smithy/upload_helper.rb +110 -0
- data/app/models/smithy/asset.rb +64 -0
- data/app/models/smithy/content.rb +35 -0
- data/app/models/smithy/content_block.rb +41 -0
- data/app/models/smithy/content_block_template.rb +26 -0
- data/app/models/smithy/image.rb +41 -0
- data/app/models/smithy/page.rb +94 -0
- data/app/models/smithy/page_content.rb +62 -0
- data/app/models/smithy/page_list.rb +61 -0
- data/app/models/smithy/page_proxy.rb +63 -0
- data/app/models/smithy/setting.rb +6 -0
- data/app/models/smithy/site.rb +30 -0
- data/app/models/smithy/template.rb +53 -0
- data/app/models/smithy/template_container.rb +16 -0
- data/app/views/layouts/smithy/application.html.erb +27 -0
- data/app/views/layouts/smithy/guides.html.erb +16 -0
- data/app/views/layouts/smithy/modal.html.erb +10 -0
- data/app/views/layouts/smithy/shared/_flash.html.erb +6 -0
- data/app/views/layouts/smithy/shared/_footer.html.erb +3 -0
- data/app/views/layouts/smithy/shared/_head.html.erb +8 -0
- data/app/views/layouts/smithy/shared/_nav.html.erb +37 -0
- data/app/views/layouts/smithy/shared/_tail.html.erb +4 -0
- data/app/views/layouts/smithy/wide.html.erb +24 -0
- data/app/views/smithy/assets/_asset.html.erb +10 -0
- data/app/views/smithy/assets/_form.html.erb +13 -0
- data/app/views/smithy/assets/_upload_form.html.erb +13 -0
- data/app/views/smithy/assets/create.js.erb +5 -0
- data/app/views/smithy/assets/edit.html.erb +5 -0
- data/app/views/smithy/assets/index.html.erb +13 -0
- data/app/views/smithy/assets/new.html.erb +13 -0
- data/app/views/smithy/caches/show.html.erb +8 -0
- data/app/views/smithy/content_blocks/_content_block.html.erb +1 -0
- data/app/views/smithy/content_blocks/_secondary_nav.html.erb +12 -0
- data/app/views/smithy/content_blocks/_template_fields.html.erb +19 -0
- data/app/views/smithy/content_blocks/edit.html.erb +31 -0
- data/app/views/smithy/content_blocks/index.html.erb +17 -0
- data/app/views/smithy/content_blocks/new.html.erb +12 -0
- data/app/views/smithy/content_pieces/edit.html.erb +13 -0
- data/app/views/smithy/content_pieces/index.html.erb +21 -0
- data/app/views/smithy/content_pieces/new.html.erb +1 -0
- data/app/views/smithy/contents/_form.html.erb +6 -0
- data/app/views/smithy/contents/_form_fields.html.erb +12 -0
- data/app/views/smithy/contents/edit.html.erb +3 -0
- data/app/views/smithy/contents/new.html.erb +3 -0
- data/app/views/smithy/guides/markdown.html.erb +150 -0
- data/app/views/smithy/images/_form.html.erb +6 -0
- data/app/views/smithy/images/_form_fields.html.erb +28 -0
- data/app/views/smithy/images/edit.html.erb +3 -0
- data/app/views/smithy/images/new.html.erb +3 -0
- data/app/views/smithy/page_contents/edit.html.erb +18 -0
- data/app/views/smithy/page_contents/new.html.erb +28 -0
- data/app/views/smithy/page_lists/_form_fields.html.erb +6 -0
- data/app/views/smithy/pages/_container.html.erb +24 -0
- data/app/views/smithy/pages/_form.html.erb +57 -0
- data/app/views/smithy/pages/_page.html.erb +6 -0
- data/app/views/smithy/pages/_page_nav.html.erb +6 -0
- data/app/views/smithy/pages/_page_related.html.erb +21 -0
- data/app/views/smithy/pages/_parent.html.erb +10 -0
- data/app/views/smithy/pages/_root.html.erb +5 -0
- data/app/views/smithy/pages/edit.html.erb +7 -0
- data/app/views/smithy/pages/index.html.erb +17 -0
- data/app/views/smithy/pages/new.html.erb +7 -0
- data/app/views/smithy/settings/_form.html.erb +7 -0
- data/app/views/smithy/settings/_setting.html.erb +6 -0
- data/app/views/smithy/settings/edit.html.erb +3 -0
- data/app/views/smithy/settings/index.html.erb +9 -0
- data/app/views/smithy/settings/new.html.erb +3 -0
- data/app/views/smithy/settings/show.html.erb +10 -0
- data/app/views/smithy/sitemap/show.xml.erb +10 -0
- data/app/views/smithy/templates/_secondary_nav.html.erb +21 -0
- data/app/views/smithy/templates/_template.html.erb +1 -0
- data/app/views/smithy/templates/edit.html.erb +36 -0
- data/app/views/smithy/templates/index.html.erb +17 -0
- data/app/views/smithy/templates/new.html.erb +13 -0
- data/config/initializers/aws.rb +5 -0
- data/config/initializers/dragonfly.rb +48 -0
- data/config/initializers/formtastic.rb +77 -0
- data/config/initializers/kaminari_config.rb +10 -0
- data/config/initializers/liquid.rb +2 -0
- data/config/routes.rb +38 -0
- data/db/migrate/20120911193140_create_smithy_templates.rb +11 -0
- data/db/migrate/20120911203618_create_smithy_settings.rb +10 -0
- data/db/migrate/20121018182146_create_smithy_pages.rb +27 -0
- data/db/migrate/20121019145543_create_smithy_template_containers.rb +11 -0
- data/db/migrate/20121019160426_create_smithy_page_contents.rb +21 -0
- data/db/migrate/20121024213357_create_smithy_content_blocks.rb +10 -0
- data/db/migrate/20121025011733_create_smithy_content_block_templates.rb +12 -0
- data/db/migrate/20121029175812_create_smithy_contents.rb +9 -0
- data/db/migrate/20121105222537_create_smithy_assets.rb +16 -0
- data/db/migrate/20121115215053_create_smithy_images.rb +15 -0
- data/db/migrate/20121127205022_add_external_link_to_smithy_pages.rb +5 -0
- data/db/migrate/20130115190505_add_markdown_content_to_smithy_contents.rb +5 -0
- data/db/migrate/20130123170918_set_defaults_for_show_in_navigation_and_cache_length.rb +6 -0
- data/db/migrate/20130311203806_create_smithy_page_lists.rb +15 -0
- data/db/migrate/20130312161116_remove_description_from_content_block.rb +5 -0
- data/db/migrate/20130326191051_add_html_attributes_to_images.rb +5 -0
- data/db/migrate/20131003210228_add_publishable_to_smithy_page_contents.rb +11 -0
- data/db/migrate/20131220160755_add_content_to_images.rb +5 -0
- data/db/migrate/20131223145710_add_position_to_smithy_template_containers.rb +5 -0
- data/lib/smithy/content_blocks/model.rb +16 -0
- data/lib/smithy/content_blocks/registry.rb +30 -0
- data/lib/smithy/content_blocks.rb +2 -0
- data/lib/smithy/content_pieces/base.rb +10 -0
- data/lib/smithy/content_pieces/registry.rb +39 -0
- data/lib/smithy/dependencies.rb +19 -0
- data/lib/smithy/dragonfly/asset_helper.rb +67 -0
- data/lib/smithy/dragonfly/remote_data_store.rb +33 -0
- data/lib/smithy/dragonfly.rb +30 -0
- data/lib/smithy/engine.rb +48 -0
- data/lib/smithy/formatter.rb +46 -0
- data/lib/smithy/liquid/database.rb +12 -0
- data/lib/smithy/liquid/drops/base.rb +16 -0
- data/lib/smithy/liquid/drops/page.rb +78 -0
- data/lib/smithy/liquid/filters/asset_tag.rb +33 -0
- data/lib/smithy/liquid/filters/resize.rb +12 -0
- data/lib/smithy/liquid/rendering.rb +50 -0
- data/lib/smithy/liquid/tags/asset.rb +54 -0
- data/lib/smithy/liquid/tags/csrf.rb +30 -0
- data/lib/smithy/liquid/tags/html.rb +61 -0
- data/lib/smithy/liquid/tags/nav.rb +76 -0
- data/lib/smithy/liquid.rb +8 -0
- data/lib/smithy/logger.rb +12 -0
- data/lib/smithy/version.rb +3 -0
- data/lib/smithy.rb +21 -0
- data/lib/smithycms.rb +1 -0
- data/lib/tasks/smithy_tasks.rake +4 -0
- data/lib/templates/erb/scaffold/_form.html.erb +11 -0
- 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,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
|