locomotivecms_steam 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +19 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +188 -0
- data/LICENSE +20 -0
- data/README.md +36 -0
- data/Rakefile +17 -0
- data/bin/publish +28 -0
- data/config/locales/de.yml +157 -0
- data/config/locales/en.yml +189 -0
- data/config/locales/es.yml +133 -0
- data/config/locales/et.yml +154 -0
- data/config/locales/fr.yml +148 -0
- data/config/locales/it.yml +155 -0
- data/config/locales/nb.yml +191 -0
- data/config/locales/nl.yml +160 -0
- data/config/locales/pl.yml +203 -0
- data/config/locales/pt-BR.yml +139 -0
- data/config/locales/ru.yml +224 -0
- data/lib/locomotive/steam/core_ext.rb +5 -0
- data/lib/locomotive/steam/core_ext/array.rb +3 -0
- data/lib/locomotive/steam/core_ext/boolean/false.rb +3 -0
- data/lib/locomotive/steam/core_ext/boolean/true.rb +3 -0
- data/lib/locomotive/steam/core_ext/hash.rb +27 -0
- data/lib/locomotive/steam/core_ext/string.rb +8 -0
- data/lib/locomotive/steam/exceptions.rb +62 -0
- data/lib/locomotive/steam/initializers.rb +5 -0
- data/lib/locomotive/steam/initializers/i18n.rb +3 -0
- data/lib/locomotive/steam/initializers/markdown.rb +27 -0
- data/lib/locomotive/steam/initializers/will_paginate.rb +16 -0
- data/lib/locomotive/steam/liquid.rb +22 -0
- data/lib/locomotive/steam/liquid/drops/base.rb +46 -0
- data/lib/locomotive/steam/liquid/drops/content_entry.rb +48 -0
- data/lib/locomotive/steam/liquid/drops/content_types.rb +117 -0
- data/lib/locomotive/steam/liquid/drops/page.rb +28 -0
- data/lib/locomotive/steam/liquid/drops/session_proxy.rb +18 -0
- data/lib/locomotive/steam/liquid/drops/site.rb +26 -0
- data/lib/locomotive/steam/liquid/errors.rb +17 -0
- data/lib/locomotive/steam/liquid/filters/date.rb +136 -0
- data/lib/locomotive/steam/liquid/filters/html.rb +188 -0
- data/lib/locomotive/steam/liquid/filters/misc.rb +49 -0
- data/lib/locomotive/steam/liquid/filters/resize.rb +18 -0
- data/lib/locomotive/steam/liquid/filters/text.rb +55 -0
- data/lib/locomotive/steam/liquid/filters/translate.rb +28 -0
- data/lib/locomotive/steam/liquid/patches.rb +47 -0
- data/lib/locomotive/steam/liquid/scopeable.rb +149 -0
- data/lib/locomotive/steam/liquid/tags/consume.rb +97 -0
- data/lib/locomotive/steam/liquid/tags/csrf.rb +34 -0
- data/lib/locomotive/steam/liquid/tags/editable.rb +6 -0
- data/lib/locomotive/steam/liquid/tags/editable/base.rb +50 -0
- data/lib/locomotive/steam/liquid/tags/editable/control.rb +19 -0
- data/lib/locomotive/steam/liquid/tags/editable/file.rb +15 -0
- data/lib/locomotive/steam/liquid/tags/editable/long_text.rb +15 -0
- data/lib/locomotive/steam/liquid/tags/editable/short_text.rb +20 -0
- data/lib/locomotive/steam/liquid/tags/editable/text.rb +15 -0
- data/lib/locomotive/steam/liquid/tags/extends.rb +25 -0
- data/lib/locomotive/steam/liquid/tags/google_analytics.rb +28 -0
- data/lib/locomotive/steam/liquid/tags/hybrid.rb +27 -0
- data/lib/locomotive/steam/liquid/tags/inline_editor.rb +16 -0
- data/lib/locomotive/steam/liquid/tags/link_to.rb +56 -0
- data/lib/locomotive/steam/liquid/tags/locale_switcher.rb +106 -0
- data/lib/locomotive/steam/liquid/tags/nav.rb +287 -0
- data/lib/locomotive/steam/liquid/tags/paginate.rb +105 -0
- data/lib/locomotive/steam/liquid/tags/path_helper.rb +98 -0
- data/lib/locomotive/steam/liquid/tags/path_to.rb +36 -0
- data/lib/locomotive/steam/liquid/tags/seo.rb +74 -0
- data/lib/locomotive/steam/liquid/tags/session_assign.rb +41 -0
- data/lib/locomotive/steam/liquid/tags/snippet.rb +63 -0
- data/lib/locomotive/steam/liquid/tags/with_scope.rb +44 -0
- data/lib/locomotive/steam/listen.rb +64 -0
- data/lib/locomotive/steam/logger.rb +54 -0
- data/lib/locomotive/steam/monkey_patches.rb +5 -0
- data/lib/locomotive/steam/monkey_patches/better_errors.rb +70 -0
- data/lib/locomotive/steam/monkey_patches/dragonfly.rb +79 -0
- data/lib/locomotive/steam/monkey_patches/haml.rb +15 -0
- data/lib/locomotive/steam/monkey_patches/httparty.rb +46 -0
- data/lib/locomotive/steam/monkey_patches/mounter.rb +32 -0
- data/lib/locomotive/steam/server.rb +81 -0
- data/lib/locomotive/steam/server/dynamic_assets.rb +33 -0
- data/lib/locomotive/steam/server/entry_submission.rb +120 -0
- data/lib/locomotive/steam/server/favicon.rb +18 -0
- data/lib/locomotive/steam/server/locale.rb +42 -0
- data/lib/locomotive/steam/server/logging.rb +32 -0
- data/lib/locomotive/steam/server/middleware.rb +61 -0
- data/lib/locomotive/steam/server/page.rb +69 -0
- data/lib/locomotive/steam/server/path.rb +34 -0
- data/lib/locomotive/steam/server/renderer.rb +118 -0
- data/lib/locomotive/steam/server/templatized_page.rb +32 -0
- data/lib/locomotive/steam/server/timezone.rb +18 -0
- data/lib/locomotive/steam/standalone_server.rb +33 -0
- data/lib/locomotive/steam/version.rb +5 -0
- data/lib/steam.rb +4 -0
- data/locomotivecms_steam.gemspec +42 -0
- data/spec/fixtures/default/README +0 -0
- data/spec/fixtures/default/app/content_types/bands.yml +19 -0
- data/spec/fixtures/default/app/content_types/events.yml +25 -0
- data/spec/fixtures/default/app/content_types/messages.yml +17 -0
- data/spec/fixtures/default/app/content_types/songs.yml +25 -0
- data/spec/fixtures/default/app/content_types/updates.yml +33 -0
- data/spec/fixtures/default/app/views/pages/404.liquid.haml +10 -0
- data/spec/fixtures/default/app/views/pages/about_us.fr.liquid.haml +7 -0
- data/spec/fixtures/default/app/views/pages/about_us.liquid.haml +21 -0
- data/spec/fixtures/default/app/views/pages/about_us.nb.liquid.haml +4 -0
- data/spec/fixtures/default/app/views/pages/about_us/jane_doe.liquid.haml +4 -0
- data/spec/fixtures/default/app/views/pages/about_us/john_doe.fr.liquid.haml +5 -0
- data/spec/fixtures/default/app/views/pages/about_us/john_doe.liquid.haml +6 -0
- data/spec/fixtures/default/app/views/pages/all.liquid.haml +13 -0
- data/spec/fixtures/default/app/views/pages/archives/news.liquid.haml +10 -0
- data/spec/fixtures/default/app/views/pages/contact.liquid.haml +54 -0
- data/spec/fixtures/default/app/views/pages/contest.liquid.haml +18 -0
- data/spec/fixtures/default/app/views/pages/events.liquid.haml +42 -0
- data/spec/fixtures/default/app/views/pages/filtered.liquid.haml +10 -0
- data/spec/fixtures/default/app/views/pages/grunge_bands.liquid.haml +8 -0
- data/spec/fixtures/default/app/views/pages/index.fr.liquid.haml +3 -0
- data/spec/fixtures/default/app/views/pages/index.liquid.haml +100 -0
- data/spec/fixtures/default/app/views/pages/music.fr.liquid.haml +4 -0
- data/spec/fixtures/default/app/views/pages/music.liquid.haml +42 -0
- data/spec/fixtures/default/app/views/pages/songs/template.fr.liquid.haml +16 -0
- data/spec/fixtures/default/app/views/pages/songs/template.liquid.haml +18 -0
- data/spec/fixtures/default/app/views/pages/songs/template/band.liquid.haml +16 -0
- data/spec/fixtures/default/app/views/pages/store.fr.liquid.haml +5 -0
- data/spec/fixtures/default/app/views/pages/store.liquid +5 -0
- data/spec/fixtures/default/app/views/pages/tags/nav.liquid.haml +6 -0
- data/spec/fixtures/default/app/views/pages/tags/nav_in_deep.liquid.haml +6 -0
- data/spec/fixtures/default/app/views/pages/unlisted_pages.liquid.haml +9 -0
- data/spec/fixtures/default/app/views/snippets/A_Complicated-one.liquid.haml +1 -0
- data/spec/fixtures/default/app/views/snippets/footer.liquid.haml +6 -0
- data/spec/fixtures/default/app/views/snippets/header.liquid.haml +1 -0
- data/spec/fixtures/default/app/views/snippets/song.fr.liquid.haml +8 -0
- data/spec/fixtures/default/app/views/snippets/song.liquid +12 -0
- data/spec/fixtures/default/config/deploy.yml +12 -0
- data/spec/fixtures/default/config/deploy_example.yml +12 -0
- data/spec/fixtures/default/config/site.yml +15 -0
- data/spec/fixtures/default/config/translations.yml +3 -0
- data/spec/fixtures/default/data/bands.yml +10 -0
- data/spec/fixtures/default/data/events.yml +53 -0
- data/spec/fixtures/default/data/songs.yml +46 -0
- data/spec/fixtures/default/data/updates.yml +48 -0
- data/spec/fixtures/default/public/fonts/chunkfive-webfont.eot +0 -0
- data/spec/fixtures/default/public/fonts/chunkfive-webfont.svg +213 -0
- data/spec/fixtures/default/public/fonts/chunkfive-webfont.ttf +0 -0
- data/spec/fixtures/default/public/fonts/chunkfive-webfont.woff +0 -0
- data/spec/fixtures/default/public/fonts/chunkfive.css +8 -0
- data/spec/fixtures/default/public/fonts/chunkfive.otf +0 -0
- data/spec/fixtures/default/public/images/nav_on.png +0 -0
- data/spec/fixtures/default/public/images/photo_frame.png +0 -0
- data/spec/fixtures/default/public/images/sep.png +0 -0
- data/spec/fixtures/default/public/images/top.jpg +0 -0
- data/spec/fixtures/default/public/javascripts/application.js.coffee +2 -0
- data/spec/fixtures/default/public/javascripts/common.js +1 -0
- data/spec/fixtures/default/public/samples/asset_collections/cover.jpg +0 -0
- data/spec/fixtures/default/public/samples/photo.jpg +0 -0
- data/spec/fixtures/default/public/samples/photo_2.jpg +0 -0
- data/spec/fixtures/default/public/stylesheets/application.css +64 -0
- data/spec/fixtures/default/public/stylesheets/other/extra.css.less +8 -0
- data/spec/fixtures/default/public/stylesheets/other/style.css.scss +13 -0
- data/spec/fixtures/default/public/stylesheets/reboot.css +82 -0
- data/spec/integration/integration_helper.rb +15 -0
- data/spec/integration/server/basic_spec.rb +170 -0
- data/spec/integration/server/contact_form_spec.rb +111 -0
- data/spec/integration/server/liquid_spec.rb +91 -0
- data/spec/integration/server/with_scope_spec.rb +20 -0
- data/spec/locales/locales_spec.rb +22 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support.rb +4 -0
- data/spec/support/examples/locale_file.rb +14 -0
- data/spec/support/examples/matching_locale.rb +8 -0
- data/spec/support/helpers.rb +22 -0
- data/spec/support/matchers/hash.rb +5 -0
- metadata +564 -0
@@ -0,0 +1,287 @@
|
|
1
|
+
module Locomotive
|
2
|
+
module Steam
|
3
|
+
module Liquid
|
4
|
+
module Tags
|
5
|
+
|
6
|
+
# Display the children pages of the site, current page or the parent page. If not precised, nav is applied on the current page.
|
7
|
+
# The html output is based on the ul/li tags.
|
8
|
+
#
|
9
|
+
# Usage:
|
10
|
+
#
|
11
|
+
# {% nav site %} => <ul class="nav"><li class="on"><a href="/features">Features</a></li></ul>
|
12
|
+
#
|
13
|
+
# {% nav site, no_wrapper: true, exclude: 'contact|about', id: 'main-nav', class: 'nav', active_class: 'on' }
|
14
|
+
#
|
15
|
+
class Nav < ::Liquid::Tag
|
16
|
+
|
17
|
+
Syntax = /(#{::Liquid::Expression}+)?/
|
18
|
+
|
19
|
+
attr_accessor :current_page, :mounting_point
|
20
|
+
|
21
|
+
def initialize(tag_name, markup, tokens, options)
|
22
|
+
if markup =~ Syntax
|
23
|
+
@source = ($1 || 'page').gsub(/"|'/, '')
|
24
|
+
|
25
|
+
self.set_options(markup, options)
|
26
|
+
else
|
27
|
+
raise ::Liquid::SyntaxError.new(options[:locale].t("errors.syntax.nav"), options[:line])
|
28
|
+
end
|
29
|
+
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def render(context)
|
34
|
+
self.set_accessors_from_context(context)
|
35
|
+
|
36
|
+
entries = self.fetch_entries
|
37
|
+
output = self.build_entries_output(entries)
|
38
|
+
|
39
|
+
if self.no_wrapper?
|
40
|
+
output
|
41
|
+
else
|
42
|
+
self.render_tag(:nav, id: @_options[:id], css: @_options[:class]) do
|
43
|
+
self.render_tag(:ul) { output }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
# Build recursively the links of all the pages.
|
51
|
+
#
|
52
|
+
# @param [ Array ] entries List of pages
|
53
|
+
#
|
54
|
+
# @return [ String ] The final HTML output
|
55
|
+
#
|
56
|
+
def build_entries_output(entries, depth = 1)
|
57
|
+
output = []
|
58
|
+
|
59
|
+
entries.each_with_index do |page, index|
|
60
|
+
css = []
|
61
|
+
css << 'first' if index == 0
|
62
|
+
css << 'last' if index == entries.size - 1
|
63
|
+
|
64
|
+
output << self.render_entry_link(page, css.join(' '), depth)
|
65
|
+
end
|
66
|
+
|
67
|
+
output.join("\n")
|
68
|
+
end
|
69
|
+
|
70
|
+
# Get all the children of a source: site (index page), parent or page.
|
71
|
+
#
|
72
|
+
# @return [ Array ] List of pages
|
73
|
+
#
|
74
|
+
def fetch_entries
|
75
|
+
children = (case @source
|
76
|
+
when 'site' then self.mounting_point.pages['index']
|
77
|
+
when 'parent' then self.current_page.parent || self.current_page
|
78
|
+
when 'page' then self.current_page
|
79
|
+
else
|
80
|
+
self.mounting_point.pages[@source]
|
81
|
+
end).children.try(:clone) || []
|
82
|
+
|
83
|
+
children.delete_if { |p| !include_page?(p) }
|
84
|
+
end
|
85
|
+
|
86
|
+
# Determine whether or not a page should be a part of the menu.
|
87
|
+
#
|
88
|
+
# @param [ Object ] page The page
|
89
|
+
#
|
90
|
+
# @return [ Boolean ] True if the page can be included or not
|
91
|
+
#
|
92
|
+
def include_page?(page)
|
93
|
+
if !page.listed? || page.templatized? || !page.published?
|
94
|
+
false
|
95
|
+
elsif @_options[:exclude]
|
96
|
+
(page.fullpath =~ @_options[:exclude]).nil?
|
97
|
+
else
|
98
|
+
true
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Determine wether or not a page is currently the displayed one.
|
103
|
+
#
|
104
|
+
# @param [ Object ] page The page
|
105
|
+
#
|
106
|
+
# @return [ Boolean ]
|
107
|
+
#
|
108
|
+
def page_selected?(page)
|
109
|
+
self.current_page.fullpath =~ /^#{page.fullpath}(\/.*)?$/
|
110
|
+
end
|
111
|
+
|
112
|
+
# Determine if the children of a page have to be rendered or not.
|
113
|
+
# It depends on the depth passed in the option.
|
114
|
+
#
|
115
|
+
# @param [ Object ] page The page
|
116
|
+
# @param [ Integer ] depth The current depth
|
117
|
+
#
|
118
|
+
# @return [ Boolean ] True if the children have to be rendered.
|
119
|
+
#
|
120
|
+
def render_children_for_page?(page, depth)
|
121
|
+
depth.succ <= @_options[:depth].to_i &&
|
122
|
+
(page.children || []).select { |child| self.include_page?(child) }.any?
|
123
|
+
end
|
124
|
+
|
125
|
+
# Return the label of an entry. It may use or not the template
|
126
|
+
# given by the snippet option.
|
127
|
+
#
|
128
|
+
# @param [ Object ] page The page
|
129
|
+
#
|
130
|
+
# @return [ String ] The label in HTML
|
131
|
+
#
|
132
|
+
def entry_label(page)
|
133
|
+
icon = @_options[:icon] ? '<span></span>' : ''
|
134
|
+
title = @_options[:liquid_render] ? @_options[:liquid_render].render('page' => page) : page.title
|
135
|
+
|
136
|
+
if icon.blank?
|
137
|
+
title
|
138
|
+
elsif @_options[:icon] == 'after'
|
139
|
+
"#{title} #{icon}"
|
140
|
+
else
|
141
|
+
"#{icon} #{title}"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Return the localized url of an entry (page).
|
146
|
+
#
|
147
|
+
# @param [ Object ] page The page
|
148
|
+
#
|
149
|
+
# @return [ String ] The localized url
|
150
|
+
#
|
151
|
+
def entry_url(page)
|
152
|
+
if ::I18n.locale.to_s == self.mounting_point.default_locale.to_s
|
153
|
+
"/#{page.fullpath}"
|
154
|
+
else
|
155
|
+
"/#{::I18n.locale}/#{page.fullpath}"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Return the css of an entry (page).
|
160
|
+
#
|
161
|
+
# @param [ Object ] page The page
|
162
|
+
# @param [ String ] css The extra css
|
163
|
+
#
|
164
|
+
# @return [ String ] The css
|
165
|
+
#
|
166
|
+
def entry_css(page, css = '')
|
167
|
+
_css = 'link'
|
168
|
+
_css += " #{page} #{@_options[:active_class]}" if self.page_selected?(page)
|
169
|
+
|
170
|
+
(_css + " #{css}").strip
|
171
|
+
end
|
172
|
+
|
173
|
+
# Return the HTML output of a page and its children if requested.
|
174
|
+
#
|
175
|
+
# @param [ Object ] page The page
|
176
|
+
# @param [ String ] css The current css to apply to the entry
|
177
|
+
# @param [ Integer] depth Used to know if the children has to be added or not.
|
178
|
+
#
|
179
|
+
# @return [ String ] The HTML output
|
180
|
+
#
|
181
|
+
def render_entry_link(page, css, depth)
|
182
|
+
url = self.entry_url(page)
|
183
|
+
label = self.entry_label(page)
|
184
|
+
css = self.entry_css(page, css)
|
185
|
+
options = ''
|
186
|
+
|
187
|
+
if self.render_children_for_page?(page, depth) && self.bootstrap?
|
188
|
+
url = '#'
|
189
|
+
label += %{ <b class="caret"></b>}
|
190
|
+
css += ' dropdown'
|
191
|
+
options = %{ class="dropdown-toggle" data-toggle="dropdown"}
|
192
|
+
end
|
193
|
+
|
194
|
+
self.render_tag(:li, id: "#{page.slug.to_s.dasherize}-link", css: css) do
|
195
|
+
children_output = depth.succ <= @_options[:depth].to_i ? self.render_entry_children(page, depth.succ) : ''
|
196
|
+
%{<a href="#{url}"#{options}>#{label}</a>} + children_output
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Recursively create a nested unordered list for the depth specified.
|
201
|
+
#
|
202
|
+
# @param [ Array ] entries The children of the page
|
203
|
+
# @param [ Integer ] depth The current depth
|
204
|
+
#
|
205
|
+
# @return [ String ] The HTML code
|
206
|
+
#
|
207
|
+
def render_entry_children(page, depth)
|
208
|
+
entries = (page.children || []).select { |child| self.include_page?(child) }
|
209
|
+
css = self.bootstrap? ? 'dropdown-menu' : ''
|
210
|
+
|
211
|
+
unless entries.empty?
|
212
|
+
self.render_tag(:ul, id: "#{@_options[:id]}-#{page.slug.to_s.dasherize}", css: css) do
|
213
|
+
self.build_entries_output(entries, depth)
|
214
|
+
end
|
215
|
+
else
|
216
|
+
''
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# Set the value (default or assigned by the tag) of the options.
|
221
|
+
#
|
222
|
+
def set_options(markup, options)
|
223
|
+
@_options = { id: 'nav', class: '', active_class: 'on', bootstrap: false, no_wrapper: false }
|
224
|
+
|
225
|
+
markup.scan(::Liquid::TagAttributes) { |key, value| @_options[key.to_sym] = value.gsub(/"|'/, '') }
|
226
|
+
|
227
|
+
@_options[:exclude] = Regexp.new(@_options[:exclude]) if @_options[:exclude]
|
228
|
+
|
229
|
+
if @_options[:snippet]
|
230
|
+
if template = self.parse_snippet_template(options, @_options[:snippet])
|
231
|
+
@_options[:liquid_render] = template
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
# Avoid to call context.registers to get the current page
|
237
|
+
# and the mounting point.
|
238
|
+
#
|
239
|
+
def set_accessors_from_context(context)
|
240
|
+
self.current_page = context.registers[:page]
|
241
|
+
self.mounting_point = context.registers[:mounting_point]
|
242
|
+
end
|
243
|
+
|
244
|
+
# Parse the template of the snippet give in option of the tag.
|
245
|
+
# If the template_name contains a liquid tag or drop, it will
|
246
|
+
# be used an inline template.
|
247
|
+
#
|
248
|
+
def parse_snippet_template(context, template_name)
|
249
|
+
source = if template_name.include?('{')
|
250
|
+
template_name
|
251
|
+
else
|
252
|
+
context[:mounting_point].snippets[template_name].try(:source)
|
253
|
+
end
|
254
|
+
|
255
|
+
source ? ::Liquid::Template.parse(source) : nil
|
256
|
+
end
|
257
|
+
|
258
|
+
# Steam any kind HTML tags. The content of the tag comes from
|
259
|
+
# the block.
|
260
|
+
#
|
261
|
+
# @param [ String ] tag_name Name of the HTML tag (li, ul, div, ...etc).
|
262
|
+
# @param [ String ] html_options Id, class, ..etc
|
263
|
+
#
|
264
|
+
# @return [ String ] The HTML
|
265
|
+
#
|
266
|
+
def render_tag(tag_name, html_options = {}, &block)
|
267
|
+
options = ['']
|
268
|
+
options << %{id="#{html_options[:id]}"} if html_options[:id].present?
|
269
|
+
options << %{class="#{html_options[:css]}"} if html_options[:css].present?
|
270
|
+
|
271
|
+
%{<#{tag_name}#{options.join(' ')}>#{yield}</#{tag_name}>}
|
272
|
+
end
|
273
|
+
|
274
|
+
def bootstrap?
|
275
|
+
@_options[:bootstrap].to_bool
|
276
|
+
end
|
277
|
+
|
278
|
+
def no_wrapper?
|
279
|
+
@_options[:no_wrapper].to_bool
|
280
|
+
end
|
281
|
+
|
282
|
+
::Liquid::Template.register_tag('nav', Nav)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Locomotive
|
2
|
+
module Steam
|
3
|
+
module Liquid
|
4
|
+
module Tags
|
5
|
+
|
6
|
+
# Paginate a collection
|
7
|
+
#
|
8
|
+
# Usage:
|
9
|
+
#
|
10
|
+
# {% paginate contents.projects by 5 %}
|
11
|
+
# {% for project in paginate.collection %}
|
12
|
+
# {{ project.name }}
|
13
|
+
# {% endfor %}
|
14
|
+
# {% endpaginate %}
|
15
|
+
#
|
16
|
+
|
17
|
+
class Paginate < ::Liquid::Block
|
18
|
+
|
19
|
+
Syntax = /(#{::Liquid::Expression}+)\s+by\s+([0-9]+)/
|
20
|
+
|
21
|
+
def initialize(tag_name, markup, tokens, options)
|
22
|
+
if markup =~ Syntax
|
23
|
+
@collection_name = $1
|
24
|
+
@per_page = $2.to_i
|
25
|
+
else
|
26
|
+
raise ::Liquid::SyntaxError.new(options[:locale].t("errors.syntax.paginate"), options[:line])
|
27
|
+
end
|
28
|
+
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
def render(context)
|
33
|
+
context.stack do
|
34
|
+
collection = context[@collection_name]
|
35
|
+
|
36
|
+
raise ::Liquid::ArgumentError.new("Cannot paginate array '#{@collection_name}'. Not found.") if collection.nil?
|
37
|
+
|
38
|
+
pagination = collection.send(:paginate, {
|
39
|
+
:page => context['current_page'],
|
40
|
+
:per_page => @per_page }).stringify_keys!
|
41
|
+
|
42
|
+
page_count, current_page = pagination['total_pages'], pagination['current_page']
|
43
|
+
|
44
|
+
path = sanitize_path(context['fullpath'])
|
45
|
+
|
46
|
+
pagination['previous'] = link(I18n.t('pagination.previous'), current_page - 1, path) if pagination['previous_page']
|
47
|
+
pagination['next'] = link(I18n.t('pagination.next'), current_page + 1, path) if pagination['next_page']
|
48
|
+
pagination['parts'] = []
|
49
|
+
|
50
|
+
hellip_break = false
|
51
|
+
|
52
|
+
if page_count > 1
|
53
|
+
1.upto(page_count) do |page|
|
54
|
+
if current_page == page
|
55
|
+
pagination['parts'] << no_link(page)
|
56
|
+
elsif page == 1
|
57
|
+
pagination['parts'] << link(page, page, path)
|
58
|
+
elsif page == page_count - 1
|
59
|
+
pagination['parts'] << link(page, page, path)
|
60
|
+
elsif page <= current_page - window_size or page >= current_page + window_size
|
61
|
+
next if hellip_break
|
62
|
+
pagination['parts'] << no_link('…')
|
63
|
+
hellip_break = true
|
64
|
+
next
|
65
|
+
else
|
66
|
+
pagination['parts'] << link(page, page, path)
|
67
|
+
end
|
68
|
+
|
69
|
+
hellip_break = false
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context['paginate'] = pagination
|
74
|
+
|
75
|
+
render_all(@nodelist, context)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def sanitize_path(path)
|
82
|
+
_path = path.gsub(/page=[0-9]+&?/, '').gsub(/_pjax=true&?/, '')
|
83
|
+
_path = _path.slice(0..-2) if _path.last == '?' || _path.last == '&'
|
84
|
+
_path
|
85
|
+
end
|
86
|
+
|
87
|
+
def window_size
|
88
|
+
3
|
89
|
+
end
|
90
|
+
|
91
|
+
def no_link(title)
|
92
|
+
{ 'title' => title, 'is_link' => false, 'hellip_break' => title == '…' }
|
93
|
+
end
|
94
|
+
|
95
|
+
def link(title, page, path)
|
96
|
+
_path = %(#{path}#{path.include?('?') ? '&' : '?'}page=#{page})
|
97
|
+
{ 'title' => title, 'url' => _path, 'is_link' => true }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
::Liquid::Template.register_tag('paginate', Paginate)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Locomotive
|
2
|
+
module Steam
|
3
|
+
module Liquid
|
4
|
+
module Tags
|
5
|
+
|
6
|
+
module PathHelper
|
7
|
+
|
8
|
+
def render_path(context, &block)
|
9
|
+
site = context.registers[:site]
|
10
|
+
|
11
|
+
if page = self.retrieve_page_from_handle(context)
|
12
|
+
path = self.public_page_fullpath(context, page)
|
13
|
+
|
14
|
+
if block_given?
|
15
|
+
block.call page, path
|
16
|
+
else
|
17
|
+
path
|
18
|
+
end
|
19
|
+
else
|
20
|
+
raise Liquid::PageNotTranslated.new(%{[link_to] Unable to find a page for the #{@handle}. Wrong handle or missing template for your content.})
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def retrieve_page_from_handle(context)
|
27
|
+
mounting_point = context.registers[:mounting_point]
|
28
|
+
|
29
|
+
context.scopes.reverse_each do |scope|
|
30
|
+
handle = scope[@handle] || @handle
|
31
|
+
|
32
|
+
page = case handle
|
33
|
+
when Locomotive::Mounter::Models::Page then handle
|
34
|
+
when Liquid::Drops::Page then handle.instance_variable_get(:@_source)
|
35
|
+
when String then fetch_page(mounting_point, handle)
|
36
|
+
when Liquid::Drops::ContentEntry then fetch_page(mounting_point, handle.instance_variable_get(:@_source), true)
|
37
|
+
when Locomotive::Mounter::Models::ContentEntry then fetch_page(mounting_point, handle, true)
|
38
|
+
else
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
42
|
+
return page unless page.nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def fetch_page(mounting_point, handle, templatized = false)
|
49
|
+
::Locomotive::Mounter.with_locale(@_options['locale']) do
|
50
|
+
if templatized
|
51
|
+
page = mounting_point.pages.values.find do |_page|
|
52
|
+
_page.templatized? &&
|
53
|
+
!_page.templatized_from_parent &&
|
54
|
+
_page.content_type.slug == handle.content_type.slug &&
|
55
|
+
(@_options['with'].nil? || _page.handle == @_options['with'])
|
56
|
+
end
|
57
|
+
|
58
|
+
page.content_entry = handle if page
|
59
|
+
|
60
|
+
page
|
61
|
+
else
|
62
|
+
mounting_point.pages.values.find { |_page| _page.handle == handle }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def public_page_fullpath(context, page)
|
68
|
+
mounting_point = context.registers[:mounting_point]
|
69
|
+
locale = @_options['locale'] || ::I18n.locale
|
70
|
+
|
71
|
+
if !page.translated_in?(locale)
|
72
|
+
title = page.title_translations.values.compact.first
|
73
|
+
raise Liquid::PageNotTranslated.new(%{the "#{title}" page is not translated in #{locale.upcase}})
|
74
|
+
end
|
75
|
+
|
76
|
+
fullpath = ::Locomotive::Mounter.with_locale(locale) do
|
77
|
+
page.fullpath.clone
|
78
|
+
end
|
79
|
+
|
80
|
+
fullpath = "#{locale}/#{fullpath}" if locale.to_s != mounting_point.default_locale.to_s
|
81
|
+
|
82
|
+
if page.templatized?
|
83
|
+
if page.content_entry._slug.nil?
|
84
|
+
title = %{#{page.content_entry.content_type.name.singularize} "#{page.content_entry.send(page.content_entry.content_type.label_field_name)}"}
|
85
|
+
raise Liquid::ContentEntryNotTranslated.new(%{the #{title} slug is not translated in #{locale.upcase}})
|
86
|
+
end
|
87
|
+
fullpath.gsub!(/(content[_-]type[_-]template|template)/, page.content_entry._slug)
|
88
|
+
end
|
89
|
+
|
90
|
+
File.join('/', fullpath)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|