trusty-cms 4.1.2 → 4.1.3
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.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/Gemfile.lock +25 -25
- data/Rakefile +7 -7
- data/app/assets/stylesheets/admin/partials/_content.scss +1 -2
- data/app/controllers/admin/assets_controller.rb +22 -21
- data/app/controllers/admin/configuration_controller.rb +9 -11
- data/app/controllers/admin/extensions_controller.rb +3 -3
- data/app/controllers/admin/layouts_controller.rb +3 -4
- data/app/controllers/admin/page_attachments_controller.rb +5 -5
- data/app/controllers/admin/page_fields_controller.rb +3 -4
- data/app/controllers/admin/page_parts_controller.rb +4 -5
- data/app/controllers/admin/pages_controller.rb +55 -56
- data/app/controllers/admin/references_controller.rb +1 -1
- data/app/controllers/admin/resource_controller.rb +132 -130
- data/app/controllers/admin/sites_controller.rb +4 -4
- data/app/controllers/admin/snippets_controller.rb +3 -4
- data/app/controllers/admin/users_controller.rb +16 -16
- data/app/controllers/application_controller.rb +47 -48
- data/app/controllers/site_controller.rb +51 -48
- data/app/controllers/social_mailer_controller.rb +13 -16
- data/app/helpers/admin/configuration_helper.rb +19 -20
- data/app/helpers/admin/layouts_helper.rb +0 -1
- data/app/helpers/admin/node_helper.rb +27 -24
- data/app/helpers/admin/pages_helper.rb +2 -2
- data/app/helpers/admin/preferences_helper.rb +0 -1
- data/app/helpers/admin/references_helper.rb +9 -10
- data/app/helpers/admin/regions_helper.rb +3 -3
- data/app/helpers/application_helper.rb +32 -33
- data/app/helpers/rad_social_helper.rb +8 -11
- data/app/helpers/scoped_helper.rb +1 -3
- data/app/helpers/sites_helper.rb +4 -4
- data/app/mailers/devise_mailer.rb +3 -4
- data/app/mailers/rad_social_mailer.rb +8 -8
- data/app/models/asset.rb +62 -63
- data/app/models/asset_type.rb +38 -39
- data/app/models/deprecated_tags.rb +3 -4
- data/app/models/file_not_found_page.rb +1 -3
- data/app/models/haml_filter.rb +1 -1
- data/app/models/layout.rb +4 -5
- data/app/models/legacy_user.rb +2 -2
- data/app/models/menu_renderer.rb +16 -18
- data/app/models/page.rb +96 -93
- data/app/models/page_attachment.rb +1 -2
- data/app/models/page_context.rb +11 -12
- data/app/models/page_part.rb +3 -4
- data/app/models/rails_page.rb +10 -12
- data/app/models/site.rb +22 -21
- data/app/models/snippet.rb +6 -8
- data/app/models/snippet_finder.rb +3 -3
- data/app/models/snippet_tags.rb +4 -4
- data/app/models/standard_tags.rb +258 -252
- data/app/models/status.rb +8 -8
- data/app/models/trusty_cms/config.rb +25 -25
- data/app/models/trusty_cms/page_response_cache_director.rb +2 -3
- data/app/models/user.rb +15 -14
- data/app/models/user_action_observer.rb +3 -3
- data/bin/rails +4 -4
- data/bin/trusty_cms +3 -5
- data/config.ru +1 -1
- data/config/application.rb +14 -15
- data/config/boot.rb +1 -2
- data/config/environment.rb +1 -1
- data/config/environments/production.rb +0 -1
- data/config/environments/test.rb +1 -2
- data/config/initializers/devise.rb +1 -1
- data/config/initializers/kraken.rb +2 -2
- data/config/initializers/tmp.rb +1 -1
- data/config/initializers/trusty_cms_config.rb +48 -48
- data/config/routes.rb +6 -6
- data/lib/active_record_extensions/active_record_extensions.rb +1 -2
- data/lib/annotatable.rb +3 -5
- data/lib/configuration_extensions/configuration_extensions.rb +1 -1
- data/lib/inheritable_class_attributes.rb +13 -9
- data/lib/login_system.rb +73 -73
- data/lib/method_observer.rb +13 -12
- data/lib/ostruct.rb +7 -10
- data/lib/simpleton.rb +0 -4
- data/lib/string_extensions/string_extensions.rb +3 -3
- data/lib/symbol_extensions/symbol_extensions.rb +1 -1
- data/lib/tasks/database.rake +28 -28
- data/lib/tasks/extensions.rake +18 -18
- data/lib/tasks/framework.rake +68 -68
- data/lib/tasks/radiant_config.rake +4 -4
- data/lib/tasks/snippets_extension_tasks.rake +11 -11
- data/lib/tasks/translate.rake +14 -14
- data/lib/tasks/upgrade_to_devise.rake +1 -1
- data/lib/translation_support.rb +22 -22
- data/lib/trusty_cms.rb +2 -2
- data/lib/trusty_cms/admin_ui.rb +19 -16
- data/lib/trusty_cms/admin_ui/region_partials.rb +4 -3
- data/lib/trusty_cms/admin_ui/region_set.rb +4 -5
- data/lib/trusty_cms/available_locales.rb +2 -4
- data/lib/trusty_cms/config/definition.rb +11 -8
- data/lib/trusty_cms/engine.rb +14 -14
- data/lib/trusty_cms/extension.rb +14 -16
- data/lib/trusty_cms/extension_loader.rb +6 -6
- data/lib/trusty_cms/extension_migrator.rb +42 -41
- data/lib/trusty_cms/extension_path.rb +20 -19
- data/lib/trusty_cms/initializer.rb +5 -8
- data/lib/trusty_cms/pagination/controller.rb +7 -10
- data/lib/trusty_cms/pagination/link_renderer.rb +2 -2
- data/lib/trusty_cms/resource_responses.rb +3 -3
- data/lib/trusty_cms/setup.rb +130 -132
- data/lib/trusty_cms/taggable.rb +19 -22
- data/lib/trusty_cms/task_support.rb +9 -6
- data/public/dispatch.fcgi +1 -1
- data/public/dispatch.rb +2 -2
- data/script/extension +1 -1
- data/script/rails +2 -2
- data/trusty_cms.gemspec +23 -23
- metadata +32 -32
|
@@ -5,7 +5,7 @@ class PageAttachment < ActiveRecord::Base
|
|
|
5
5
|
|
|
6
6
|
accepts_nested_attributes_for :asset
|
|
7
7
|
|
|
8
|
-
acts_as_list :
|
|
8
|
+
acts_as_list scope: :page_id
|
|
9
9
|
|
|
10
10
|
def selected?
|
|
11
11
|
!!selected
|
|
@@ -16,5 +16,4 @@ class PageAttachment < ActiveRecord::Base
|
|
|
16
16
|
def add_to_list_bottom
|
|
17
17
|
self[position_column] ||= bottom_position_in_list.to_i + 1
|
|
18
18
|
end
|
|
19
|
-
|
|
20
19
|
end
|
data/app/models/page_context.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
class PageContext < Radius::Context
|
|
2
|
-
|
|
3
2
|
attr_reader :page
|
|
4
3
|
|
|
5
4
|
def initialize(page)
|
|
@@ -25,23 +24,23 @@ class PageContext < Radius::Context
|
|
|
25
24
|
super
|
|
26
25
|
rescue Exception => e
|
|
27
26
|
raise e if raise_errors?
|
|
27
|
+
|
|
28
28
|
@tag_binding_stack.pop unless @tag_binding_stack.last == binding
|
|
29
29
|
render_error_message(e.message)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
private
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def set_process_variables(page)
|
|
39
|
-
page.request ||= @page.request
|
|
40
|
-
page.response ||= @page.response
|
|
41
|
-
end
|
|
34
|
+
def render_error_message(message)
|
|
35
|
+
"<div><strong>#{message}</strong></div>"
|
|
36
|
+
end
|
|
42
37
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
def set_process_variables(page)
|
|
39
|
+
page.request ||= @page.request
|
|
40
|
+
page.response ||= @page.response
|
|
41
|
+
end
|
|
46
42
|
|
|
43
|
+
def raise_errors?
|
|
44
|
+
Rails.env != 'production'
|
|
45
|
+
end
|
|
47
46
|
end
|
data/app/models/page_part.rb
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
class PagePart < ActiveRecord::Base
|
|
2
|
-
|
|
3
2
|
# Default Order
|
|
4
|
-
default_scope {order(
|
|
3
|
+
default_scope { order('name') }
|
|
5
4
|
|
|
6
5
|
# Associations
|
|
7
6
|
belongs_to :page
|
|
8
7
|
|
|
9
8
|
# Validations
|
|
10
9
|
validates_presence_of :name
|
|
11
|
-
validates_length_of :name, :
|
|
12
|
-
validates_length_of :filter_id, :
|
|
10
|
+
validates_length_of :name, maximum: 100
|
|
11
|
+
validates_length_of :filter_id, maximum: 25, allow_nil: true
|
|
13
12
|
|
|
14
13
|
object_id_attr :filter, TextFilter
|
|
15
14
|
|
data/app/models/rails_page.rb
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
class RailsPage < Page
|
|
2
|
-
|
|
3
|
-
display_name "Application"
|
|
2
|
+
display_name 'Application'
|
|
4
3
|
attr_accessor :breadcrumbs
|
|
5
4
|
|
|
6
|
-
def find_by_url(url, live=true, clean=true)
|
|
5
|
+
def find_by_url(url, live = true, clean = true)
|
|
7
6
|
found_page = super
|
|
8
7
|
if found_page.nil? || found_page.is_a?(FileNotFoundPage)
|
|
9
8
|
url = clean_url(url) if clean
|
|
@@ -12,22 +11,22 @@ class RailsPage < Page
|
|
|
12
11
|
found_page
|
|
13
12
|
end
|
|
14
13
|
end
|
|
15
|
-
|
|
14
|
+
|
|
16
15
|
def url=(path)
|
|
17
16
|
@url = path
|
|
18
17
|
end
|
|
19
|
-
|
|
18
|
+
|
|
20
19
|
def url
|
|
21
20
|
@url || super
|
|
22
21
|
end
|
|
23
|
-
|
|
22
|
+
|
|
24
23
|
def build_parts_from_hash!(content)
|
|
25
|
-
content.each do |k,v|
|
|
26
|
-
(part(k) || parts.build(:
|
|
24
|
+
content.each do |k, v|
|
|
25
|
+
(part(k) || parts.build(name: k.to_s, filter_id: '')).content = v
|
|
27
26
|
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
alias_method
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
alias_method 'tag:old_breadcrumbs', 'tag:breadcrumbs'
|
|
31
30
|
tag 'breadcrumbs' do |tag|
|
|
32
31
|
if tag.locals.page.is_a?(RailsPage) && tag.locals.page.breadcrumbs
|
|
33
32
|
tag.locals.page.breadcrumbs
|
|
@@ -35,5 +34,4 @@ class RailsPage < Page
|
|
|
35
34
|
render_tag('old_breadcrumbs', tag)
|
|
36
35
|
end
|
|
37
36
|
end
|
|
38
|
-
|
|
39
37
|
end
|
data/app/models/site.rb
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
class Site < ActiveRecord::Base
|
|
5
5
|
acts_as_list
|
|
6
|
-
belongs_to :created_by, :
|
|
7
|
-
belongs_to :updated_by, :
|
|
8
|
-
belongs_to :production_homepage
|
|
6
|
+
belongs_to :created_by, class_name: 'User'
|
|
7
|
+
belongs_to :updated_by, class_name: 'User'
|
|
8
|
+
belongs_to :production_homepage, class_name: 'ProductionPage'
|
|
9
9
|
|
|
10
|
-
default_scope {order('position ASC')}
|
|
10
|
+
default_scope { order('position ASC') }
|
|
11
11
|
|
|
12
12
|
class << self
|
|
13
13
|
attr_accessor :several
|
|
@@ -16,7 +16,8 @@ class Site < ActiveRecord::Base
|
|
|
16
16
|
|
|
17
17
|
def find_for_host(hostname = '')
|
|
18
18
|
return default if hostname.blank?
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
sites = includes(:homepage).where('domain IS NOT NULL')
|
|
20
21
|
site = sites.find { |site| hostname == site.base_domain || hostname =~ Regexp.compile(site.domain) }
|
|
21
22
|
site || default
|
|
22
23
|
end
|
|
@@ -30,12 +31,12 @@ class Site < ActiveRecord::Base
|
|
|
30
31
|
# If none is found, we are probably brand new, so a workable default site is created.
|
|
31
32
|
|
|
32
33
|
def catchall
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
create({
|
|
35
|
+
domain: '',
|
|
36
|
+
name: 'default_site',
|
|
37
|
+
base_domain: 'localhost',
|
|
38
|
+
homepage: Page.find_by_parent_id(nil),
|
|
39
|
+
})
|
|
39
40
|
end
|
|
40
41
|
|
|
41
42
|
# Returns true if more than one site is present. This is normally only used to make interface decisions, eg whether to show the site-chooser dropdown.
|
|
@@ -45,7 +46,7 @@ class Site < ActiveRecord::Base
|
|
|
45
46
|
end
|
|
46
47
|
end
|
|
47
48
|
|
|
48
|
-
belongs_to :homepage, :
|
|
49
|
+
belongs_to :homepage, class_name: 'Page', foreign_key: 'homepage_id'
|
|
49
50
|
validates_presence_of :name, :base_domain
|
|
50
51
|
validates_uniqueness_of :domain
|
|
51
52
|
|
|
@@ -54,27 +55,27 @@ class Site < ActiveRecord::Base
|
|
|
54
55
|
|
|
55
56
|
# Returns the fully specified web address for the supplied path, or the root of this site if no path is given.
|
|
56
57
|
|
|
57
|
-
def url(path =
|
|
58
|
-
uri = URI.join("http://#{
|
|
58
|
+
def url(path = '/')
|
|
59
|
+
uri = URI.join("http://#{base_domain}", path)
|
|
59
60
|
uri.to_s
|
|
60
61
|
end
|
|
61
62
|
|
|
62
63
|
# Returns the fully specified web address for the development version of this site and the supplied path, or the root of this site if no path is given.
|
|
63
64
|
|
|
64
|
-
def dev_url(path =
|
|
65
|
-
uri = URI.join("http://#{TrustyCms::Config['dev.host'] || 'dev'}.#{
|
|
65
|
+
def dev_url(path = '/')
|
|
66
|
+
uri = URI.join("http://#{TrustyCms::Config['dev.host'] || 'dev'}.#{base_domain}", path)
|
|
66
67
|
uri.to_s
|
|
67
68
|
end
|
|
68
69
|
|
|
69
70
|
def create_homepage
|
|
70
|
-
if
|
|
71
|
-
self.homepage =
|
|
72
|
-
|
|
71
|
+
if homepage_id.blank?
|
|
72
|
+
self.homepage = build_homepage(title: "#{name} Homepage",
|
|
73
|
+
slug: name.to_slug.to_s, breadcrumb: 'Home')
|
|
73
74
|
default_status = TrustyCms::Config['defaults.page.status']
|
|
74
|
-
|
|
75
|
+
homepage.status = Status[default_status] if default_status
|
|
75
76
|
default_parts = TrustyCms::Config['defaults.page.parts'].to_s.strip.split(/\s*,\s*/)
|
|
76
77
|
default_parts.each do |name|
|
|
77
|
-
|
|
78
|
+
homepage.parts << PagePart.new(name: name, filter_id: TrustyCms::Config['defaults.page.filter'])
|
|
78
79
|
end
|
|
79
80
|
save
|
|
80
81
|
end
|
data/app/models/snippet.rb
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
class Snippet < ActiveRecord::Base
|
|
2
|
-
|
|
3
2
|
# Default Order
|
|
4
|
-
default_scope {order('name')}
|
|
3
|
+
default_scope { order('name') }
|
|
5
4
|
|
|
6
5
|
# Associations
|
|
7
|
-
belongs_to :created_by, :
|
|
8
|
-
belongs_to :updated_by, :
|
|
6
|
+
belongs_to :created_by, class_name: 'User'
|
|
7
|
+
belongs_to :updated_by, class_name: 'User'
|
|
9
8
|
|
|
10
9
|
# Validations
|
|
11
10
|
validates_presence_of :name
|
|
12
|
-
validates_length_of :name, :
|
|
13
|
-
validates_length_of :filter_id, :
|
|
14
|
-
validates_format_of :name, :
|
|
11
|
+
validates_length_of :name, maximum: 100
|
|
12
|
+
validates_length_of :filter_id, maximum: 25, allow_nil: true
|
|
13
|
+
validates_format_of :name, with: %r{\A\S*\z}
|
|
15
14
|
validates_uniqueness_of :name
|
|
16
15
|
|
|
17
16
|
object_id_attr :filter, TextFilter
|
|
@@ -19,5 +18,4 @@ class Snippet < ActiveRecord::Base
|
|
|
19
18
|
def after_initialize
|
|
20
19
|
self.filter_id ||= TrustyCms::Config['defaults.snippet.filter'] if new_record?
|
|
21
20
|
end
|
|
22
|
-
|
|
23
21
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class SnippetFinder
|
|
2
2
|
class << self
|
|
3
3
|
def find(id)
|
|
4
|
-
find_map('find',id)
|
|
4
|
+
find_map('find', id)
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
def find_by_name(name)
|
|
@@ -15,10 +15,10 @@ class SnippetFinder
|
|
|
15
15
|
private
|
|
16
16
|
|
|
17
17
|
def find_map(meth, *args)
|
|
18
|
-
finder_types.find
|
|
18
|
+
finder_types.find do |type|
|
|
19
19
|
found = type.send(meth, *args)
|
|
20
20
|
return found if found
|
|
21
|
-
|
|
21
|
+
end
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
end
|
data/app/models/snippet_tags.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module SnippetTags
|
|
2
2
|
include TrustyCms::Taggable
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
class TagError < StandardError; end
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
desc %{
|
|
7
7
|
Renders the snippet specified in the @name@ attribute within the context of a page.
|
|
8
8
|
|
|
@@ -22,7 +22,7 @@ module SnippetTags
|
|
|
22
22
|
name = tag['name']
|
|
23
23
|
|
|
24
24
|
snippet = snippet_cache(name.strip)
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
if snippet
|
|
27
27
|
tag.locals.yield = tag.expand if tag.double?
|
|
28
28
|
tag.globals.page.render_snippet(snippet)
|
|
@@ -48,7 +48,7 @@ module SnippetTags
|
|
|
48
48
|
the snippet is called as a double tag.
|
|
49
49
|
|
|
50
50
|
*Usage (within a snippet):*
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
<pre><code>
|
|
53
53
|
<div id="outer">
|
|
54
54
|
<p>before</p>
|
data/app/models/standard_tags.rb
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
require 'trusty_cms/taggable'
|
|
2
2
|
require 'local_time'
|
|
3
3
|
module StandardTags
|
|
4
|
-
|
|
5
4
|
include TrustyCms::Taggable
|
|
6
5
|
include LocalTime
|
|
7
6
|
|
|
8
|
-
require
|
|
7
|
+
require 'will_paginate/view_helpers'
|
|
9
8
|
include WillPaginate::ViewHelpers
|
|
10
9
|
|
|
11
10
|
class TagError < StandardError; end
|
|
@@ -22,7 +21,7 @@ module StandardTags
|
|
|
22
21
|
tag.expand
|
|
23
22
|
end
|
|
24
23
|
|
|
25
|
-
[
|
|
24
|
+
%i[breadcrumb slug title].each do |method|
|
|
26
25
|
desc %{
|
|
27
26
|
Renders the @#{method}@ attribute of the current page.
|
|
28
27
|
}
|
|
@@ -37,7 +36,7 @@ module StandardTags
|
|
|
37
36
|
tag 'path' do |tag|
|
|
38
37
|
relative_url_for(tag.locals.page.path, tag.globals.page.request)
|
|
39
38
|
end
|
|
40
|
-
deprecated_tag 'url', :
|
|
39
|
+
deprecated_tag 'url', substitute: 'path', deadline: '1.2'
|
|
41
40
|
|
|
42
41
|
desc %{
|
|
43
42
|
Gives access to a page's children.
|
|
@@ -171,7 +170,6 @@ module StandardTags
|
|
|
171
170
|
tag.expand if tag.locals.first_child
|
|
172
171
|
end
|
|
173
172
|
|
|
174
|
-
|
|
175
173
|
desc %{
|
|
176
174
|
Renders the tag contents unless the current page is the first child in the context of
|
|
177
175
|
a children:each tag
|
|
@@ -208,7 +206,6 @@ module StandardTags
|
|
|
208
206
|
tag.expand if tag.locals.last_child
|
|
209
207
|
end
|
|
210
208
|
|
|
211
|
-
|
|
212
209
|
desc %{
|
|
213
210
|
Renders the tag contents unless the current page is the last child in the context of
|
|
214
211
|
a children:each tag
|
|
@@ -271,7 +268,7 @@ module StandardTags
|
|
|
271
268
|
|
|
272
269
|
<pre><code><r:parent>...</r:parent></code></pre>
|
|
273
270
|
}
|
|
274
|
-
tag
|
|
271
|
+
tag 'parent' do |tag|
|
|
275
272
|
parent = tag.locals.page.parent
|
|
276
273
|
tag.locals.page = parent
|
|
277
274
|
tag.expand if parent
|
|
@@ -285,7 +282,7 @@ module StandardTags
|
|
|
285
282
|
|
|
286
283
|
<pre><code><r:if_parent>...</r:if_parent></code></pre>
|
|
287
284
|
}
|
|
288
|
-
tag
|
|
285
|
+
tag 'if_parent' do |tag|
|
|
289
286
|
parent = tag.locals.page.parent
|
|
290
287
|
tag.expand if parent
|
|
291
288
|
end
|
|
@@ -298,7 +295,7 @@ module StandardTags
|
|
|
298
295
|
|
|
299
296
|
<pre><code><r:unless_parent>...</r:unless_parent></code></pre>
|
|
300
297
|
}
|
|
301
|
-
tag
|
|
298
|
+
tag 'unless_parent' do |tag|
|
|
302
299
|
parent = tag.locals.page.parent
|
|
303
300
|
tag.expand unless parent
|
|
304
301
|
end
|
|
@@ -313,7 +310,7 @@ module StandardTags
|
|
|
313
310
|
|
|
314
311
|
<pre><code><r:if_children [status="published"]>...</r:if_children></code></pre>
|
|
315
312
|
}
|
|
316
|
-
tag
|
|
313
|
+
tag 'if_children' do |tag|
|
|
317
314
|
children = tag.locals.page.children.where(children_find_options(tag)[:conditions]).count
|
|
318
315
|
tag.expand if children > 0
|
|
319
316
|
end
|
|
@@ -328,12 +325,12 @@ module StandardTags
|
|
|
328
325
|
|
|
329
326
|
<pre><code><r:unless_children [status="published"]>...</r:unless_children></code></pre>
|
|
330
327
|
}
|
|
331
|
-
tag
|
|
328
|
+
tag 'unless_children' do |tag|
|
|
332
329
|
children = tag.locals.page.children.where(children_find_options(tag)[:conditions]).count
|
|
333
330
|
tag.expand unless children > 0
|
|
334
331
|
end
|
|
335
332
|
|
|
336
|
-
|
|
333
|
+
desc %{
|
|
337
334
|
Aggregates the children of multiple paths using the @paths@ attribute.
|
|
338
335
|
Useful for combining many different sections/categories into a single
|
|
339
336
|
feed or listing.
|
|
@@ -342,10 +339,10 @@ module StandardTags
|
|
|
342
339
|
|
|
343
340
|
<pre><code><r:aggregate paths="/section1; /section2; /section3"> ... </r:aggregate></code></pre>
|
|
344
341
|
}
|
|
345
|
-
tag
|
|
342
|
+
tag 'aggregate' do |tag|
|
|
346
343
|
required_attr(tag, 'paths', 'urls')
|
|
347
|
-
paths = (tag.attr['paths']||tag.attr[
|
|
348
|
-
parent_ids = paths.map {|u| Page.find_by_path(u) }.map(&:id)
|
|
344
|
+
paths = (tag.attr['paths'] || tag.attr['urls']).split(';').map(&:strip).reject(&:blank?).map { |u| clean_path u }
|
|
345
|
+
parent_ids = paths.map { |u| Page.find_by_path(u) }.map(&:id)
|
|
349
346
|
tag.locals.parent_ids = parent_ids
|
|
350
347
|
tag.expand
|
|
351
348
|
end
|
|
@@ -358,9 +355,9 @@ module StandardTags
|
|
|
358
355
|
|
|
359
356
|
<pre><code><r:aggregate:each paths="/section1; /section2; /section3"> ... </r:aggregate:each></code></pre>
|
|
360
357
|
}
|
|
361
|
-
tag
|
|
358
|
+
tag 'aggregate:each' do |tag|
|
|
362
359
|
aggregates = []
|
|
363
|
-
tag.locals.aggregated_pages = tag.locals.parent_ids.map {|p| Page.find(p)}
|
|
360
|
+
tag.locals.aggregated_pages = tag.locals.parent_ids.map { |p| Page.find(p) }
|
|
364
361
|
tag.locals.aggregated_pages.each do |aggregate_page|
|
|
365
362
|
tag.locals.page = aggregate_page
|
|
366
363
|
aggregates << tag.expand
|
|
@@ -368,12 +365,12 @@ module StandardTags
|
|
|
368
365
|
aggregates.flatten.join('')
|
|
369
366
|
end
|
|
370
367
|
|
|
371
|
-
tag
|
|
368
|
+
tag 'aggregate:each:children' do |tag|
|
|
372
369
|
tag.locals.children = tag.locals.page.children
|
|
373
370
|
tag.expand
|
|
374
371
|
end
|
|
375
372
|
|
|
376
|
-
tag
|
|
373
|
+
tag 'aggregate:each:children:each' do |tag|
|
|
377
374
|
options = children_find_options(tag)
|
|
378
375
|
result = []
|
|
379
376
|
children = tag.locals.children
|
|
@@ -386,7 +383,7 @@ module StandardTags
|
|
|
386
383
|
result.flatten.join('')
|
|
387
384
|
end
|
|
388
385
|
|
|
389
|
-
tag
|
|
386
|
+
tag 'aggregate:children' do |tag|
|
|
390
387
|
tag.expand
|
|
391
388
|
end
|
|
392
389
|
|
|
@@ -400,10 +397,10 @@ module StandardTags
|
|
|
400
397
|
<r:children:count />
|
|
401
398
|
</r:aggregate></code></pre>
|
|
402
399
|
}
|
|
403
|
-
tag
|
|
400
|
+
tag 'aggregate:children:count' do |tag|
|
|
404
401
|
options = aggregate_children(tag)
|
|
405
402
|
if ActiveRecord::Base.connection.adapter_name.downcase == 'postgresql'
|
|
406
|
-
options[:group] = Page.columns.map {|c| c.name}.join(', ')
|
|
403
|
+
options[:group] = Page.columns.map { |c| c.name }.join(', ')
|
|
407
404
|
Page.where(options).size
|
|
408
405
|
else
|
|
409
406
|
Page.where(options).count
|
|
@@ -421,8 +418,8 @@ module StandardTags
|
|
|
421
418
|
</r:children:each>
|
|
422
419
|
</r:aggregate></code></pre>
|
|
423
420
|
}
|
|
424
|
-
tag
|
|
425
|
-
render_children_with_pagination(tag, :
|
|
421
|
+
tag 'aggregate:children:each' do |tag|
|
|
422
|
+
render_children_with_pagination(tag, aggregate: true)
|
|
426
423
|
end
|
|
427
424
|
|
|
428
425
|
desc %{
|
|
@@ -437,7 +434,7 @@ module StandardTags
|
|
|
437
434
|
</r:children:first>
|
|
438
435
|
</r:aggregate></code></pre>
|
|
439
436
|
}
|
|
440
|
-
tag
|
|
437
|
+
tag 'aggregate:children:first' do |tag|
|
|
441
438
|
options = aggregate_children(tag)
|
|
442
439
|
children = Page.where(options)
|
|
443
440
|
|
|
@@ -459,7 +456,7 @@ module StandardTags
|
|
|
459
456
|
</r:children:last>
|
|
460
457
|
</r:aggregate></code></pre>
|
|
461
458
|
}
|
|
462
|
-
tag
|
|
459
|
+
tag 'aggregate:children:last' do |tag|
|
|
463
460
|
options = aggregate_children(tag)
|
|
464
461
|
children = Page.where(options)
|
|
465
462
|
|
|
@@ -485,16 +482,16 @@ module StandardTags
|
|
|
485
482
|
tag 'cycle' do |tag|
|
|
486
483
|
cycle = (tag.globals.cycle ||= {})
|
|
487
484
|
if tag.attr['values']
|
|
488
|
-
values = tag.attr['values'].split(
|
|
485
|
+
values = tag.attr['values'].split(',').collect(&:strip)
|
|
489
486
|
end
|
|
490
487
|
start = tag.attr['start']
|
|
491
488
|
cycle_name = tag.attr['name'] || 'cycle'
|
|
492
489
|
if values
|
|
493
|
-
if start
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
490
|
+
current_index = if start
|
|
491
|
+
(cycle[cycle_name] ||= values.index(start))
|
|
492
|
+
else
|
|
493
|
+
(cycle[cycle_name] ||= 0)
|
|
494
|
+
end
|
|
498
495
|
current_index = 0 if tag.attr['reset'] == 'true'
|
|
499
496
|
cycle[cycle_name] = (current_index + 1) % values.size
|
|
500
497
|
values[current_index]
|
|
@@ -527,20 +524,21 @@ module StandardTags
|
|
|
527
524
|
page = tag.locals.page
|
|
528
525
|
part_name = tag_part_name(tag)
|
|
529
526
|
# Prevent simple and deep recursive rendering of the same page part
|
|
530
|
-
rendering_parts = (tag.locals.rendering_parts ||= Hash.new {|h,k| h[k] = []})
|
|
527
|
+
rendering_parts = (tag.locals.rendering_parts ||= Hash.new { |h, k| h[k] = [] })
|
|
531
528
|
if rendering_parts[page.id].include?(part_name)
|
|
532
529
|
raise TagError.new(%{Recursion error: already rendering the `#{part_name}' part.})
|
|
533
530
|
else
|
|
534
531
|
rendering_parts[page.id] << part_name
|
|
535
532
|
end
|
|
536
|
-
|
|
533
|
+
|
|
534
|
+
inherit = boolean_attr_or_error(tag, 'inherit', false)
|
|
537
535
|
part_page = page
|
|
538
536
|
if inherit
|
|
539
|
-
while
|
|
537
|
+
while part_page.part(part_name).nil? && (not part_page.parent.nil?)
|
|
540
538
|
part_page = part_page.parent
|
|
541
539
|
end
|
|
542
540
|
end
|
|
543
|
-
contextual = boolean_attr_or_error(tag,'contextual', true)
|
|
541
|
+
contextual = boolean_attr_or_error(tag, 'contextual', true)
|
|
544
542
|
part = part_page.part(part_name)
|
|
545
543
|
tag.locals.page = part_page unless contextual
|
|
546
544
|
result = tag.globals.page.render_snippet(part) unless part.nil?
|
|
@@ -566,21 +564,21 @@ module StandardTags
|
|
|
566
564
|
part_name = tag_part_name(tag)
|
|
567
565
|
parts_arr = part_name.split(',')
|
|
568
566
|
inherit = boolean_attr_or_error(tag, 'inherit', 'false')
|
|
569
|
-
find = attr_or_error(tag, :
|
|
567
|
+
find = attr_or_error(tag, attribute_name: 'find', default: 'all', values: 'any, all')
|
|
570
568
|
expandable = true
|
|
571
569
|
one_found = false
|
|
572
570
|
parts_arr.each do |name|
|
|
573
571
|
part_page = tag.locals.page
|
|
574
572
|
name.strip!
|
|
575
573
|
if inherit
|
|
576
|
-
while
|
|
574
|
+
while part_page.part(name).nil? && (not part_page.parent.nil?)
|
|
577
575
|
part_page = part_page.parent
|
|
578
576
|
end
|
|
579
577
|
end
|
|
580
578
|
expandable = false if part_page.part(name).nil?
|
|
581
579
|
one_found ||= true if !part_page.part(name).nil?
|
|
582
580
|
end
|
|
583
|
-
expandable = true if (find == 'any'
|
|
581
|
+
expandable = true if (find == 'any') && one_found
|
|
584
582
|
tag.expand if expandable
|
|
585
583
|
end
|
|
586
584
|
|
|
@@ -601,20 +599,21 @@ module StandardTags
|
|
|
601
599
|
part_name = tag_part_name(tag)
|
|
602
600
|
parts_arr = part_name.split(',')
|
|
603
601
|
inherit = boolean_attr_or_error(tag, 'inherit', false)
|
|
604
|
-
find = attr_or_error(tag, :
|
|
605
|
-
expandable
|
|
602
|
+
find = attr_or_error(tag, attribute_name: 'find', default: 'all', values: 'any, all')
|
|
603
|
+
expandable = true
|
|
604
|
+
all_found = true
|
|
606
605
|
parts_arr.each do |name|
|
|
607
606
|
part_page = tag.locals.page
|
|
608
607
|
name.strip!
|
|
609
608
|
if inherit
|
|
610
|
-
while
|
|
609
|
+
while part_page.part(name).nil? && (not part_page.parent.nil?)
|
|
611
610
|
part_page = part_page.parent
|
|
612
611
|
end
|
|
613
612
|
end
|
|
614
613
|
expandable = false if !part_page.part(name).nil?
|
|
615
614
|
all_found = false if part_page.part(name).nil?
|
|
616
615
|
end
|
|
617
|
-
if all_found == false
|
|
616
|
+
if (all_found == false) && (find == 'all')
|
|
618
617
|
expandable = true
|
|
619
618
|
end
|
|
620
619
|
tag.expand if expandable
|
|
@@ -630,13 +629,13 @@ module StandardTags
|
|
|
630
629
|
<pre><code><r:if_path matches="regexp" [ignore_case="true|false"]>...</r:if_path></code></pre>
|
|
631
630
|
}
|
|
632
631
|
tag 'if_path' do |tag|
|
|
633
|
-
required_attr(tag,'matches')
|
|
632
|
+
required_attr(tag, 'matches')
|
|
634
633
|
regexp = build_regexp_for(tag, 'matches')
|
|
635
634
|
unless tag.locals.page.path.match(regexp).nil?
|
|
636
|
-
|
|
635
|
+
tag.expand
|
|
637
636
|
end
|
|
638
637
|
end
|
|
639
|
-
deprecated_tag 'if_url', :
|
|
638
|
+
deprecated_tag 'if_url', substitute: 'if_path', deadline: '1.2'
|
|
640
639
|
|
|
641
640
|
desc %{
|
|
642
641
|
The opposite of the @if_path@ tag.
|
|
@@ -649,10 +648,10 @@ module StandardTags
|
|
|
649
648
|
required_attr(tag, 'matches')
|
|
650
649
|
regexp = build_regexp_for(tag, 'matches')
|
|
651
650
|
if tag.locals.page.path.match(regexp).nil?
|
|
652
|
-
|
|
651
|
+
tag.expand
|
|
653
652
|
end
|
|
654
653
|
end
|
|
655
|
-
deprecated_tag 'unless_url', :
|
|
654
|
+
deprecated_tag 'unless_url', substitute: 'unless_path', deadline: '1.2'
|
|
656
655
|
|
|
657
656
|
desc %{
|
|
658
657
|
Renders the contained elements if the current contextual page is either the actual page or one of its parents.
|
|
@@ -663,7 +662,7 @@ module StandardTags
|
|
|
663
662
|
|
|
664
663
|
<pre><code><r:if_ancestor_or_self>...</r:if_ancestor_or_self></code></pre>
|
|
665
664
|
}
|
|
666
|
-
tag
|
|
665
|
+
tag 'if_ancestor_or_self' do |tag|
|
|
667
666
|
tag.expand if (tag.globals.page.ancestors + [tag.globals.page]).include?(tag.locals.page)
|
|
668
667
|
end
|
|
669
668
|
|
|
@@ -676,7 +675,7 @@ module StandardTags
|
|
|
676
675
|
|
|
677
676
|
<pre><code><r:unless_ancestor_or_self>...</r:unless_ancestor_or_self></code></pre>
|
|
678
677
|
}
|
|
679
|
-
tag
|
|
678
|
+
tag 'unless_ancestor_or_self' do |tag|
|
|
680
679
|
tag.expand unless (tag.globals.page.ancestors + [tag.globals.page]).include?(tag.locals.page)
|
|
681
680
|
end
|
|
682
681
|
|
|
@@ -689,7 +688,7 @@ module StandardTags
|
|
|
689
688
|
|
|
690
689
|
<pre><code><r:if_self>...</r:if_self></code></pre>
|
|
691
690
|
}
|
|
692
|
-
tag
|
|
691
|
+
tag 'if_self' do |tag|
|
|
693
692
|
tag.expand if tag.locals.page == tag.globals.page
|
|
694
693
|
end
|
|
695
694
|
|
|
@@ -702,7 +701,7 @@ module StandardTags
|
|
|
702
701
|
|
|
703
702
|
<pre><code><r:unless_self>...</r:unless_self></code></pre>
|
|
704
703
|
}
|
|
705
|
-
tag
|
|
704
|
+
tag 'unless_self' do |tag|
|
|
706
705
|
tag.expand unless tag.locals.page == tag.globals.page
|
|
707
706
|
end
|
|
708
707
|
|
|
@@ -739,7 +738,9 @@ module StandardTags
|
|
|
739
738
|
local_avatar_url = "/images/admin/avatar_#{([size.to_i] * 2).join('x')}.png"
|
|
740
739
|
default_avatar_url = "#{request.protocol}#{request.host_with_port}#{local_avatar_url}"
|
|
741
740
|
|
|
742
|
-
|
|
741
|
+
if email.blank?
|
|
742
|
+
local_avatar_url
|
|
743
|
+
else
|
|
743
744
|
url = '//gravatar.com/avatar/'
|
|
744
745
|
url << "#{Digest::MD5.new.update(email)}?"
|
|
745
746
|
url << "rating=#{rating}"
|
|
@@ -747,12 +748,10 @@ module StandardTags
|
|
|
747
748
|
url << "&default=#{default_avatar_url}" unless request.host_with_port == 'testhost.tld'
|
|
748
749
|
# Test the Gravatar url
|
|
749
750
|
require 'open-uri'
|
|
750
|
-
begin; open "http:#{sanitize(url)}", :
|
|
751
|
-
rescue; local_avatar_url
|
|
751
|
+
begin; open "http:#{sanitize(url)}", proxy: true
|
|
752
|
+
rescue StandardError; local_avatar_url
|
|
752
753
|
else; url
|
|
753
754
|
end
|
|
754
|
-
else
|
|
755
|
-
local_avatar_url
|
|
756
755
|
end
|
|
757
756
|
end
|
|
758
757
|
|
|
@@ -773,24 +772,29 @@ module StandardTags
|
|
|
773
772
|
format = (tag.attr['format'] || '%A, %B %d, %Y')
|
|
774
773
|
time_attr = tag.attr['for']
|
|
775
774
|
date = if time_attr
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
page.published_at || page.created_at
|
|
775
|
+
if time_attr == 'now'
|
|
776
|
+
Time.zone.now
|
|
777
|
+
elsif Page.date_column_names.include?(time_attr)
|
|
778
|
+
page[time_attr]
|
|
779
|
+
else
|
|
780
|
+
raise TagError, "Invalid value for 'for' attribute."
|
|
781
|
+
end
|
|
782
|
+
else
|
|
783
|
+
page.published_at || page.created_at
|
|
786
784
|
end
|
|
787
785
|
case format
|
|
788
786
|
when 'rfc1123'
|
|
789
787
|
CGI.rfc1123_date(date.to_time)
|
|
790
788
|
else
|
|
791
|
-
@i18n_date_format_keys ||=
|
|
792
|
-
|
|
793
|
-
|
|
789
|
+
@i18n_date_format_keys ||= begin
|
|
790
|
+
begin
|
|
791
|
+
I18n.config.backend.send(:translations)[I18n.locale][:date][:formats].keys
|
|
792
|
+
rescue StandardError
|
|
793
|
+
[]
|
|
794
|
+
end
|
|
795
|
+
end
|
|
796
|
+
format = @i18n_date_format_keys.include?(format.to_sym) ? format.to_sym : format
|
|
797
|
+
I18n.l date, format: format
|
|
794
798
|
end
|
|
795
799
|
end
|
|
796
800
|
|
|
@@ -858,7 +862,7 @@ module StandardTags
|
|
|
858
862
|
<pre><code><r:find path="value_to_find">...</r:find></code></pre>
|
|
859
863
|
}
|
|
860
864
|
tag 'find' do |tag|
|
|
861
|
-
required_attr(tag,'path','url')
|
|
865
|
+
required_attr(tag, 'path', 'url')
|
|
862
866
|
path = tag.attr['path'] || tag.attr['url']
|
|
863
867
|
|
|
864
868
|
found = Page.find_by_path(absolute_path_for(tag.locals.page.path, path))
|
|
@@ -885,7 +889,7 @@ module StandardTags
|
|
|
885
889
|
tag.expand
|
|
886
890
|
options = tag.locals.random
|
|
887
891
|
option = options[rand(options.size)]
|
|
888
|
-
option
|
|
892
|
+
option
|
|
889
893
|
end
|
|
890
894
|
tag 'random:option' do |tag|
|
|
891
895
|
items = tag.locals.random
|
|
@@ -909,7 +913,7 @@ module StandardTags
|
|
|
909
913
|
|
|
910
914
|
<pre><code><r:escape_html>...</r:escape_html></code></pre>
|
|
911
915
|
}
|
|
912
|
-
tag
|
|
916
|
+
tag 'escape_html' do |tag|
|
|
913
917
|
CGI.escapeHTML(tag.expand)
|
|
914
918
|
end
|
|
915
919
|
|
|
@@ -943,9 +947,10 @@ module StandardTags
|
|
|
943
947
|
hash = tag.locals.navigation = {}
|
|
944
948
|
tag.expand
|
|
945
949
|
raise TagError.new("`navigation' tag must include a `normal' tag") unless hash.has_key? :normal
|
|
950
|
+
|
|
946
951
|
ActiveSupport::Deprecation.warn("The 'urls' attribute of the r:navigation tag has been deprecated in favour of 'paths'. Please update your site.") if tag.attr['urls']
|
|
947
952
|
result = []
|
|
948
|
-
pairs = (tag.attr['paths']||tag.attr['urls']).to_s.split('|').map do |pair|
|
|
953
|
+
pairs = (tag.attr['paths'] || tag.attr['urls']).to_s.split('|').map do |pair|
|
|
949
954
|
parts = pair.split(':')
|
|
950
955
|
value = parts.pop
|
|
951
956
|
key = parts.join(':')
|
|
@@ -953,36 +958,36 @@ module StandardTags
|
|
|
953
958
|
end
|
|
954
959
|
pairs.each_with_index do |(title, path), i|
|
|
955
960
|
compare_path = remove_trailing_slash(path)
|
|
956
|
-
page_path = remove_trailing_slash(
|
|
961
|
+
page_path = remove_trailing_slash(path)
|
|
957
962
|
hash[:title] = title
|
|
958
963
|
hash[:path] = path
|
|
959
964
|
tag.locals.first_child = i == 0
|
|
960
965
|
tag.locals.last_child = i == pairs.length - 1
|
|
961
|
-
case page_path
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
966
|
+
result << case page_path
|
|
967
|
+
when compare_path
|
|
968
|
+
(hash[:here] || hash[:selected] || hash[:normal]).call
|
|
969
|
+
when Regexp.compile('^' + Regexp.quote(path))
|
|
970
|
+
(hash[:selected] || hash[:normal]).call
|
|
971
|
+
else
|
|
972
|
+
hash[:normal].call
|
|
973
|
+
end
|
|
969
974
|
end
|
|
970
975
|
between = hash.has_key?(:between) ? hash[:between].call : ' '
|
|
971
976
|
result.reject { |i| i.blank? }.join(between)
|
|
972
977
|
end
|
|
973
|
-
[
|
|
978
|
+
%i[normal here selected between].each do |symbol|
|
|
974
979
|
tag "navigation:#{symbol}" do |tag|
|
|
975
980
|
hash = tag.locals.navigation
|
|
976
981
|
hash[symbol] = tag.block
|
|
977
982
|
end
|
|
978
983
|
end
|
|
979
|
-
[
|
|
984
|
+
%i[title path].each do |symbol|
|
|
980
985
|
tag "navigation:#{symbol}" do |tag|
|
|
981
986
|
hash = tag.locals.navigation
|
|
982
987
|
hash[symbol]
|
|
983
988
|
end
|
|
984
989
|
end
|
|
985
|
-
tag
|
|
990
|
+
tag 'navigation:url' do |tag|
|
|
986
991
|
hash = tag.locals.navigation
|
|
987
992
|
ActiveSupport::Deprecation.warn("The 'r:navigation:url' tag has been deprecated in favour of 'r:navigation:path'. Please update your site.")
|
|
988
993
|
hash[:path]
|
|
@@ -1069,6 +1074,7 @@ module StandardTags
|
|
|
1069
1074
|
tag 'status' do |tag|
|
|
1070
1075
|
status = tag.globals.page.status.name
|
|
1071
1076
|
return status.downcase if tag.attr['downcase']
|
|
1077
|
+
|
|
1072
1078
|
status
|
|
1073
1079
|
end
|
|
1074
1080
|
|
|
@@ -1080,7 +1086,7 @@ module StandardTags
|
|
|
1080
1086
|
<pre><code><r:field name="Keywords" /></code></pre>
|
|
1081
1087
|
)
|
|
1082
1088
|
tag 'field' do |tag|
|
|
1083
|
-
required_attr(tag,'name')
|
|
1089
|
+
required_attr(tag, 'name')
|
|
1084
1090
|
tag.locals.page.field(tag.attr['name']).try(:content)
|
|
1085
1091
|
end
|
|
1086
1092
|
|
|
@@ -1095,14 +1101,14 @@ module StandardTags
|
|
|
1095
1101
|
<pre><code><r:if_field name="author" [equals|matches="John"] [ignore_case="true|false"]>...</r:if_field></code></pre>
|
|
1096
1102
|
)
|
|
1097
1103
|
tag 'if_field' do |tag|
|
|
1098
|
-
required_attr(tag,'name')
|
|
1104
|
+
required_attr(tag, 'name')
|
|
1099
1105
|
field = tag.locals.page.field(tag.attr['name'])
|
|
1100
1106
|
return '' if field.nil?
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1107
|
+
|
|
1108
|
+
tag.expand if if tag.attr['equals'] && (tag.attr['ignore_case'] == 'false') then field.content == tag.attr['equals']
|
|
1109
|
+
elsif tag.attr['equals'] then field.content.downcase == tag.attr['equals'].downcase
|
|
1110
|
+
elsif tag.attr['matches'] then field.content =~ build_regexp_for(tag, 'matches')
|
|
1111
|
+
else field
|
|
1106
1112
|
end
|
|
1107
1113
|
end
|
|
1108
1114
|
|
|
@@ -1117,13 +1123,12 @@ module StandardTags
|
|
|
1117
1123
|
<pre><code><r:unless_field name="author" [equals|matches="John"] [ignore_case="true|false"]>...</r:unless_field></code></pre>
|
|
1118
1124
|
)
|
|
1119
1125
|
tag 'unless_field' do |tag|
|
|
1120
|
-
required_attr(tag,'name')
|
|
1126
|
+
required_attr(tag, 'name')
|
|
1121
1127
|
field = tag.locals.page.field(tag.attr['name'])
|
|
1122
|
-
tag.expand unless
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
else field
|
|
1128
|
+
tag.expand unless if field && (tag.attr['equals'] && (tag.attr['ignore_case'] == 'false')) then field.content == tag.attr['equals']
|
|
1129
|
+
elsif field && tag.attr['equals'] then field.content.downcase == tag.attr['equals'].downcase
|
|
1130
|
+
elsif field && tag.attr['matches'] then field.content =~ build_regexp_for(tag, 'matches')
|
|
1131
|
+
else field
|
|
1127
1132
|
end
|
|
1128
1133
|
end
|
|
1129
1134
|
|
|
@@ -1133,20 +1138,20 @@ module StandardTags
|
|
|
1133
1138
|
desc %{
|
|
1134
1139
|
Returns TrustyCms::Config['site.title'] as configured under the Settings tab.
|
|
1135
1140
|
}
|
|
1136
|
-
tag
|
|
1137
|
-
TrustyCms::Config[
|
|
1141
|
+
tag 'site:title' do |_tag|
|
|
1142
|
+
TrustyCms::Config['site.title']
|
|
1138
1143
|
end
|
|
1139
1144
|
desc %{
|
|
1140
1145
|
Returns TrustyCms::Config['site.host'] as configured under the Settings tab.
|
|
1141
1146
|
}
|
|
1142
|
-
tag
|
|
1143
|
-
TrustyCms::Config[
|
|
1147
|
+
tag 'site:host' do |_tag|
|
|
1148
|
+
TrustyCms::Config['site.host']
|
|
1144
1149
|
end
|
|
1145
1150
|
desc %{
|
|
1146
1151
|
Returns TrustyCms::Config['dev.host'] as configured under the Settings tab.
|
|
1147
1152
|
}
|
|
1148
|
-
tag
|
|
1149
|
-
TrustyCms::Config[
|
|
1153
|
+
tag 'site:dev_host' do |_tag|
|
|
1154
|
+
TrustyCms::Config['dev.host']
|
|
1150
1155
|
end
|
|
1151
1156
|
|
|
1152
1157
|
tag 'meta:description' do |tag|
|
|
@@ -1159,7 +1164,7 @@ module StandardTags
|
|
|
1159
1164
|
end
|
|
1160
1165
|
end
|
|
1161
1166
|
|
|
1162
|
-
|
|
1167
|
+
tag 'meta:keywords' do |tag|
|
|
1163
1168
|
show_tag = tag.attr['tag'] != 'false' || false
|
|
1164
1169
|
keywords = CGI.escapeHTML(tag.locals.page.field(:keywords).try(:content)) if tag.locals.page.field(:keywords)
|
|
1165
1170
|
if show_tag
|
|
@@ -1169,183 +1174,184 @@ module StandardTags
|
|
|
1169
1174
|
end
|
|
1170
1175
|
end
|
|
1171
1176
|
|
|
1172
|
-
desc
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
end
|
|
1177
|
+
desc 'Widget of sharing icons'
|
|
1178
|
+
tag 'rad_share_widget' do |tag|
|
|
1179
|
+
attributes = tag.attr.to_options
|
|
1180
|
+
url = attributes[:url].nil? ? request.url : attributes[:url]
|
|
1181
|
+
message = attributes[:message].nil? ? "Check out #{tag.locals.page.title}." : attributes[:message]
|
|
1182
|
+
email_subject = attributes[:email_subject].nil? ? tag.locals.page.title : attributes[:email_subject]
|
|
1183
|
+
email_message = attributes[:email_message].nil? ? "I thought you might be interested in this: #{url}" : "#{attributes[:email_message]} #{url}"
|
|
1184
|
+
email_action_url = attributes[:email_action_url].nil? ? '/rad_social/mail' : attributes[:email_action_url]
|
|
1185
|
+
request.env['action_controller.instance'].render_to_string partial: 'widget/horizontal_widget',
|
|
1186
|
+
locals: { url: url,
|
|
1187
|
+
message: message,
|
|
1188
|
+
email_subject: email_subject,
|
|
1189
|
+
email_message: email_message,
|
|
1190
|
+
email_action_url: email_action_url }
|
|
1191
|
+
end
|
|
1188
1192
|
|
|
1189
1193
|
private
|
|
1190
|
-
def render_children_with_pagination(tag, opts={})
|
|
1191
|
-
if opts[:aggregate]
|
|
1192
|
-
findable = Page
|
|
1193
|
-
options = aggregate_children(tag)
|
|
1194
|
-
else
|
|
1195
|
-
findable = tag.locals.children
|
|
1196
|
-
options = children_find_options(tag)
|
|
1197
|
-
end
|
|
1198
|
-
paging = pagination_find_options(tag)
|
|
1199
|
-
result = []
|
|
1200
|
-
tag.locals.previous_headers = {}
|
|
1201
|
-
displayed_children = paging ? findable.paginate(options.merge(paging)) : findable.all.where(options[:conditions]).order(options[:order])
|
|
1202
|
-
displayed_children.each_with_index do |item, i|
|
|
1203
|
-
tag.locals.child = item
|
|
1204
|
-
tag.locals.page = item
|
|
1205
|
-
tag.locals.first_child = i == 0
|
|
1206
|
-
tag.locals.last_child = i == displayed_children.length - 1
|
|
1207
|
-
result << tag.expand
|
|
1208
|
-
end
|
|
1209
|
-
if paging && displayed_children.total_pages > 1
|
|
1210
|
-
tag.locals.paginated_list = displayed_children
|
|
1211
|
-
result << tag.render('pagination', tag.attr.dup)
|
|
1212
|
-
end
|
|
1213
|
-
result.flatten.join('')
|
|
1214
|
-
end
|
|
1215
1194
|
|
|
1216
|
-
|
|
1217
|
-
|
|
1195
|
+
def render_children_with_pagination(tag, opts = {})
|
|
1196
|
+
if opts[:aggregate]
|
|
1197
|
+
findable = Page
|
|
1198
|
+
options = aggregate_children(tag)
|
|
1199
|
+
else
|
|
1200
|
+
findable = tag.locals.children
|
|
1201
|
+
options = children_find_options(tag)
|
|
1202
|
+
end
|
|
1203
|
+
paging = pagination_find_options(tag)
|
|
1204
|
+
result = []
|
|
1205
|
+
tag.locals.previous_headers = {}
|
|
1206
|
+
displayed_children = paging ? findable.paginate(options.merge(paging)) : findable.all.where(options[:conditions]).order(options[:order])
|
|
1207
|
+
displayed_children.each_with_index do |item, i|
|
|
1208
|
+
tag.locals.child = item
|
|
1209
|
+
tag.locals.page = item
|
|
1210
|
+
tag.locals.first_child = i == 0
|
|
1211
|
+
tag.locals.last_child = i == displayed_children.length - 1
|
|
1212
|
+
result << tag.expand
|
|
1213
|
+
end
|
|
1214
|
+
if paging && displayed_children.total_pages > 1
|
|
1215
|
+
tag.locals.paginated_list = displayed_children
|
|
1216
|
+
result << tag.render('pagination', tag.attr.dup)
|
|
1217
|
+
end
|
|
1218
|
+
result.flatten.join('')
|
|
1219
|
+
end
|
|
1218
1220
|
|
|
1219
|
-
|
|
1221
|
+
def children_find_options(tag)
|
|
1222
|
+
attr = tag.attr.symbolize_keys
|
|
1220
1223
|
|
|
1221
|
-
|
|
1222
|
-
if number = attr[symbol]
|
|
1223
|
-
if number =~ /^\d+$/
|
|
1224
|
-
options[symbol] = number.to_i
|
|
1225
|
-
else
|
|
1226
|
-
raise TagError.new("`#{symbol}' attribute must be a positive number")
|
|
1227
|
-
end
|
|
1228
|
-
end
|
|
1229
|
-
end
|
|
1224
|
+
options = {}
|
|
1230
1225
|
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
order_string << by
|
|
1236
|
-
else
|
|
1237
|
-
raise TagError.new("`by' attribute of `each' tag must be set to a valid field name")
|
|
1238
|
-
end
|
|
1239
|
-
if order =~ /^(asc|desc)$/i
|
|
1240
|
-
order_string << " #{$1.upcase}"
|
|
1241
|
-
else
|
|
1242
|
-
raise TagError.new(%{`order' attribute of `each' tag must be set to either "asc" or "desc"})
|
|
1243
|
-
end
|
|
1244
|
-
options[:order] = order_string
|
|
1245
|
-
|
|
1246
|
-
status = (attr[:status] || ( dev?(tag.globals.page.request) ? 'all' : 'published')).downcase
|
|
1247
|
-
unless status == 'all'
|
|
1248
|
-
stat = Status[status]
|
|
1249
|
-
unless stat.nil?
|
|
1250
|
-
options[:conditions] = ["(virtual = ?) and (status_id = ?)", false, stat.id]
|
|
1226
|
+
%i[limit offset].each do |symbol|
|
|
1227
|
+
if number = attr[symbol]
|
|
1228
|
+
if number =~ /^\d+$/
|
|
1229
|
+
options[symbol] = number.to_i
|
|
1251
1230
|
else
|
|
1252
|
-
raise TagError.new(
|
|
1231
|
+
raise TagError.new("`#{symbol}' attribute must be a positive number")
|
|
1253
1232
|
end
|
|
1254
|
-
else
|
|
1255
|
-
options[:conditions] = ["virtual = ?", false]
|
|
1256
1233
|
end
|
|
1257
|
-
options
|
|
1258
1234
|
end
|
|
1259
1235
|
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
options
|
|
1236
|
+
by = (attr[:by] || 'published_at').strip
|
|
1237
|
+
order = (attr[:order] || 'asc').strip
|
|
1238
|
+
order_string = ''
|
|
1239
|
+
if attributes.keys.include?(by)
|
|
1240
|
+
order_string << by
|
|
1241
|
+
else
|
|
1242
|
+
raise TagError.new("`by' attribute of `each' tag must be set to a valid field name")
|
|
1268
1243
|
end
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
pagination_parameters.merge(attr.slice(:per_page))
|
|
1274
|
-
else
|
|
1275
|
-
false
|
|
1276
|
-
end
|
|
1244
|
+
if order =~ /^(asc|desc)$/i
|
|
1245
|
+
order_string << " #{$1.upcase}"
|
|
1246
|
+
else
|
|
1247
|
+
raise TagError.new(%{`order' attribute of `each' tag must be set to either "asc" or "desc"})
|
|
1277
1248
|
end
|
|
1249
|
+
options[:order] = order_string
|
|
1278
1250
|
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1251
|
+
status = (attr[:status] || (dev?(tag.globals.page.request) ? 'all' : 'published')).downcase
|
|
1252
|
+
if status == 'all'
|
|
1253
|
+
options[:conditions] = ['virtual = ?', false]
|
|
1254
|
+
else
|
|
1255
|
+
stat = Status[status]
|
|
1256
|
+
if stat.nil?
|
|
1257
|
+
raise TagError.new(%{`status' attribute of `each' tag must be set to a valid status})
|
|
1283
1258
|
else
|
|
1284
|
-
|
|
1259
|
+
options[:conditions] = ['(virtual = ?) and (status_id = ?)', false, stat.id]
|
|
1285
1260
|
end
|
|
1286
1261
|
end
|
|
1262
|
+
options
|
|
1263
|
+
end
|
|
1287
1264
|
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1265
|
+
def aggregate_children(tag)
|
|
1266
|
+
options = children_find_options(tag)
|
|
1267
|
+
parent_ids = tag.locals.parent_ids
|
|
1291
1268
|
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1269
|
+
conditions = options[:conditions]
|
|
1270
|
+
conditions.first << ' AND parent_id IN (?)'
|
|
1271
|
+
conditions << parent_ids
|
|
1272
|
+
options
|
|
1273
|
+
end
|
|
1295
1274
|
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
end
|
|
1303
|
-
regexp
|
|
1275
|
+
def pagination_find_options(tag)
|
|
1276
|
+
attr = tag.attr.symbolize_keys
|
|
1277
|
+
if attr[:paginated] == 'true'
|
|
1278
|
+
pagination_parameters.merge(attr.slice(:per_page))
|
|
1279
|
+
else
|
|
1280
|
+
false
|
|
1304
1281
|
end
|
|
1282
|
+
end
|
|
1305
1283
|
|
|
1306
|
-
|
|
1307
|
-
|
|
1284
|
+
def will_paginate_options(tag)
|
|
1285
|
+
attr = tag.attr.symbolize_keys
|
|
1286
|
+
if attr[:paginated] == 'true'
|
|
1287
|
+
attr.slice(:class, :previous_label, :next_label, :inner_window, :outer_window, :separator, :per_page).merge({ renderer: TrustyCms::Pagination::LinkRenderer.new(tag.globals.page.path) })
|
|
1288
|
+
else
|
|
1289
|
+
{}
|
|
1308
1290
|
end
|
|
1291
|
+
end
|
|
1309
1292
|
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
else
|
|
1314
|
-
File.expand_path(File.join(base_path, new_path))
|
|
1315
|
-
end
|
|
1316
|
-
end
|
|
1293
|
+
def remove_trailing_slash(string)
|
|
1294
|
+
string =~ %r{^(.*?)/$} ? $1 : string
|
|
1295
|
+
end
|
|
1317
1296
|
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1297
|
+
def tag_part_name(tag)
|
|
1298
|
+
tag.attr['part'] || 'body'
|
|
1299
|
+
end
|
|
1321
1300
|
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1301
|
+
def build_regexp_for(tag, attribute_name)
|
|
1302
|
+
ignore_case = tag.attr.has_key?('ignore_case') && tag.attr['ignore_case'] == 'false' ? nil : true
|
|
1303
|
+
begin
|
|
1304
|
+
regexp = Regexp.new(tag.attr['matches'], ignore_case)
|
|
1305
|
+
rescue RegexpError => e
|
|
1306
|
+
raise TagError.new("Malformed regular expression in `#{attribute_name}' argument of `#{tag.name}' tag: #{e.message}")
|
|
1325
1307
|
end
|
|
1308
|
+
regexp
|
|
1309
|
+
end
|
|
1326
1310
|
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
values = options[:values].split(',').map!(&:strip)
|
|
1311
|
+
def relative_url_for(url, _request)
|
|
1312
|
+
File.join(ActionController::Base.relative_url_root || '', url)
|
|
1313
|
+
end
|
|
1331
1314
|
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1315
|
+
def absolute_path_for(base_path, new_path)
|
|
1316
|
+
if new_path.first == '/'
|
|
1317
|
+
new_path
|
|
1318
|
+
else
|
|
1319
|
+
File.expand_path(File.join(base_path, new_path))
|
|
1335
1320
|
end
|
|
1321
|
+
end
|
|
1336
1322
|
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
end
|
|
1323
|
+
def page_found?(page)
|
|
1324
|
+
page && !(FileNotFoundPage === page)
|
|
1325
|
+
end
|
|
1341
1326
|
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1327
|
+
def boolean_attr_or_error(tag, attribute_name, default)
|
|
1328
|
+
attribute = attr_or_error(tag, attribute_name: attribute_name, default: default.to_s, values: 'true, false')
|
|
1329
|
+
attribute.to_s.downcase == 'true'
|
|
1330
|
+
end
|
|
1331
|
+
|
|
1332
|
+
def attr_or_error(tag, options = {})
|
|
1333
|
+
attribute_name = options[:attribute_name].to_s
|
|
1334
|
+
default = options[:default]
|
|
1335
|
+
values = options[:values].split(',').map!(&:strip)
|
|
1336
|
+
|
|
1337
|
+
attribute = (tag.attr[attribute_name] || default).to_s
|
|
1338
|
+
raise TagError.new(%{`#{attribute_name}' attribute of `#{tag.name}' tag must be one of: #{values.join(', ')}}) unless values.include?(attribute)
|
|
1339
|
+
|
|
1340
|
+
attribute
|
|
1341
|
+
end
|
|
1350
1342
|
|
|
1343
|
+
def required_attr(tag, *attribute_names)
|
|
1344
|
+
attr_collection = attribute_names.map { |a| "`#{a}'" }.join(' or ')
|
|
1345
|
+
raise TagError.new("`#{tag.name}' tag must contain a #{attr_collection} attribute.") if (tag.attr.keys & attribute_names).blank?
|
|
1346
|
+
end
|
|
1347
|
+
|
|
1348
|
+
def dev?(request)
|
|
1349
|
+
return false if request.nil?
|
|
1350
|
+
|
|
1351
|
+
if dev_host = TrustyCms::Config['dev.host']
|
|
1352
|
+
dev_host == request.host
|
|
1353
|
+
else
|
|
1354
|
+
request.host =~ /^dev\./
|
|
1355
|
+
end
|
|
1356
|
+
end
|
|
1351
1357
|
end
|