alula 0.2.3 → 0.4.0b
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/.gitignore +2 -0
- data/Gemfile +7 -0
- data/Guardfile +9 -0
- data/Rakefile +12 -1
- data/VERSION +1 -1
- data/alula.gemspec +20 -4
- data/lib/alula/attachment_processor.rb +77 -0
- data/lib/alula/cdn.rb +30 -0
- data/lib/alula/cdns/edgecast.rb +16 -0
- data/lib/alula/cdns/hosts.rb +14 -0
- data/lib/alula/cli.rb +90 -39
- data/lib/alula/compressors.rb +22 -10
- data/lib/alula/config.rb +141 -0
- data/lib/alula/content.rb +113 -0
- data/lib/alula/contents/attachment.rb +8 -0
- data/lib/alula/contents/item.rb +409 -0
- data/lib/alula/contents/metadata.rb +73 -0
- data/lib/alula/contents/page.rb +9 -0
- data/lib/alula/contents/post.rb +32 -0
- data/lib/alula/context.rb +72 -0
- data/lib/alula/core_ext.rb +5 -0
- data/lib/alula/core_ext/environment.rb +20 -0
- data/lib/alula/core_ext/filter.rb +20 -0
- data/lib/alula/core_ext/filters/smilies.rb +36 -0
- data/lib/alula/core_ext/manifest.rb +30 -0
- data/lib/alula/core_ext/tag.rb +100 -0
- data/lib/alula/core_ext/tags/attachment.rb +28 -0
- data/lib/alula/core_ext/tags/blockquote.rb +21 -0
- data/lib/alula/core_ext/tags/image.rb +48 -0
- data/lib/alula/core_ext/tags/locale.rb +17 -0
- data/lib/alula/core_ext/tags/video.rb +103 -0
- data/lib/alula/generator.rb +31 -0
- data/lib/alula/generators/feedbuilder.rb +44 -0
- data/lib/alula/generators/paginate.rb +88 -0
- data/lib/alula/generators/sitemap.rb +26 -0
- data/lib/alula/helpers.rb +2 -0
- data/lib/alula/helpers/addons.rb +12 -0
- data/lib/alula/helpers/assets.rb +56 -0
- data/lib/alula/helpers/url_helpers.rb +16 -0
- data/lib/alula/plugin.rb +32 -0
- data/lib/alula/processor.rb +86 -0
- data/lib/alula/processors/dummy.rb +24 -0
- data/lib/alula/processors/image.rb +52 -0
- data/lib/alula/processors/magick.rb +83 -0
- data/lib/alula/processors/video.rb +97 -0
- data/lib/alula/processors/zencoder.rb +199 -0
- data/lib/alula/progress.rb +95 -0
- data/lib/alula/progressbar.rb +66 -0
- data/lib/alula/site.rb +331 -262
- data/lib/alula/storage.rb +46 -0
- data/lib/alula/storages/file_item.rb +43 -0
- data/lib/alula/storages/filestorage.rb +96 -0
- data/lib/alula/storages/item.rb +12 -0
- data/lib/alula/support/commonlogger.rb +30 -0
- data/lib/alula/theme.rb +70 -13
- data/lib/alula/theme/layout.rb +56 -0
- data/lib/alula/theme/view.rb +43 -0
- data/lib/alula/version.rb +1 -1
- data/locales/en.yml +9 -0
- data/locales/fi.yml +10 -0
- data/locales/l10n/ar.yml +199 -0
- data/locales/l10n/az.yml +199 -0
- data/locales/l10n/bg.yml +199 -0
- data/locales/l10n/bn-IN.yml +182 -0
- data/locales/l10n/bs.yml +242 -0
- data/locales/l10n/ca.yml +199 -0
- data/locales/l10n/cs.yml +198 -0
- data/locales/l10n/csb.yml +210 -0
- data/locales/l10n/cy.yml +199 -0
- data/locales/l10n/da.yml +199 -0
- data/locales/l10n/de-AT.yml +203 -0
- data/locales/l10n/de-CH.yml +203 -0
- data/locales/l10n/de.yml +203 -0
- data/locales/l10n/dsb.yml +215 -0
- data/locales/l10n/el.yml +199 -0
- data/locales/l10n/en-AU.yml +205 -0
- data/locales/l10n/en-CA.yml +214 -0
- data/locales/l10n/en-GB.yml +205 -0
- data/locales/l10n/en-IN.yml +205 -0
- data/locales/l10n/en-US.yml +205 -0
- data/locales/l10n/en.yml +205 -0
- data/locales/l10n/eo.yml +201 -0
- data/locales/l10n/es-AR.yml +205 -0
- data/locales/l10n/es-CL.yml +199 -0
- data/locales/l10n/es-CO.yml +205 -0
- data/locales/l10n/es-MX.yml +205 -0
- data/locales/l10n/es-PE.yml +181 -0
- data/locales/l10n/es-VE.yml +205 -0
- data/locales/l10n/es.yml +199 -0
- data/locales/l10n/et.yml +199 -0
- data/locales/l10n/eu.yml +199 -0
- data/locales/l10n/fa.yml +199 -0
- data/locales/l10n/fi.yml +199 -0
- data/locales/l10n/fr-CA.yml +207 -0
- data/locales/l10n/fr-CH.yml +207 -0
- data/locales/l10n/fr.yml +222 -0
- data/locales/l10n/fur.yml +199 -0
- data/locales/l10n/gl-ES.yml +178 -0
- data/locales/l10n/gsw-CH.yml +199 -0
- data/locales/l10n/he.yml +201 -0
- data/locales/l10n/hi-IN.yml +199 -0
- data/locales/l10n/hi.yml +199 -0
- data/locales/l10n/hr.yml +237 -0
- data/locales/l10n/hsb.yml +214 -0
- data/locales/l10n/hu.yml +199 -0
- data/locales/l10n/id.yml +200 -0
- data/locales/l10n/is.yml +213 -0
- data/locales/l10n/it.yml +205 -0
- data/locales/l10n/ja.yml +197 -0
- data/locales/l10n/kn.yml +199 -0
- data/locales/l10n/ko.yml +197 -0
- data/locales/l10n/lo.yml +186 -0
- data/locales/l10n/lt.yml +182 -0
- data/locales/l10n/lv.yml +215 -0
- data/locales/l10n/mk.yml +170 -0
- data/locales/l10n/mn.yml +205 -0
- data/locales/l10n/nb.yml +207 -0
- data/locales/l10n/nl.yml +199 -0
- data/locales/l10n/nn.yml +160 -0
- data/locales/l10n/pl.yml +221 -0
- data/locales/l10n/pt-BR.yml +207 -0
- data/locales/l10n/pt-PT.yml +207 -0
- data/locales/l10n/quotes.yml +24 -0
- data/locales/l10n/rm.yml +182 -0
- data/locales/l10n/ro.yml +199 -0
- data/locales/l10n/ru.yml +257 -0
- data/locales/l10n/sk.yml +213 -0
- data/locales/l10n/sl.yml +210 -0
- data/locales/l10n/sr-Latn.yml +170 -0
- data/locales/l10n/sr.yml +170 -0
- data/locales/l10n/sv-SE.yml +199 -0
- data/locales/l10n/sw.yml +197 -0
- data/locales/l10n/th.yml +173 -0
- data/locales/l10n/tl.yml +229 -0
- data/locales/l10n/tr.yml +199 -0
- data/locales/l10n/uk.yml +257 -0
- data/locales/l10n/vi.yml +201 -0
- data/locales/l10n/wo.yml +205 -0
- data/locales/l10n/zh-CN.yml +199 -0
- data/locales/l10n/zh-TW.yml +199 -0
- data/template/Gemfile.erb +14 -4
- data/template/README +16 -0
- data/template/config.yml.erb +42 -38
- data/test/fixtures/config_001_simple.yml +2 -0
- data/test/fixtures/config_002_l10n.yml +5 -0
- data/test/fixtures/pages/invalid-page.markdown +1 -0
- data/test/fixtures/pages/multilingual-page.markdown +20 -0
- data/test/fixtures/pages/section/subpage.markdown +5 -0
- data/test/fixtures/pages/simple-page.markdown +7 -0
- data/test/fixtures/posts/2012-07-02-invalid-post.markdown +1 -0
- data/test/fixtures/posts/2012-07-02-simple.markdown +7 -0
- data/test/fixtures/posts/2012-07-03-full-metadata.markdown +8 -0
- data/test/fixtures/posts/2012-07-03-multilingual-full-metadata.markdown +20 -0
- data/test/fixtures/theme/test/layouts/default.html.erb +1 -0
- data/test/fixtures/theme/test/views/page.html.erb +1 -0
- data/test/fixtures/theme/test/views/post.html.erb +1 -0
- data/test/minitest_helper.rb +14 -0
- data/test/test_config.rb +33 -0
- data/test/test_content.rb +30 -0
- data/test/test_metadata.rb +83 -0
- data/test/test_page.rb +81 -0
- data/test/test_post.rb +123 -0
- data/test/test_storage.rb +23 -0
- data/test/test_storage_file.rb +32 -0
- data/test/test_theme.rb +45 -0
- data/vendor/assets/images/favicon.png +0 -0
- data/vendor/assets/images/grey.gif +0 -0
- data/vendor/assets/javascripts/jquery.alula.js.coffee +16 -0
- data/vendor/{javascripts → assets/javascripts}/jquery.js +0 -0
- data/vendor/assets/javascripts/jquery.lazyload.js +210 -0
- data/vendor/assets/javascripts/lazyload.js.coffee +15 -0
- data/vendor/layouts/feed.xml.builder +19 -0
- data/vendor/layouts/sitemap.xml.builder +10 -0
- data/vendor/views/feed_post.html.haml +1 -0
- metadata +529 -50
- data/lib/alula.rb +0 -5
- data/lib/alula/assethelper.rb +0 -75
- data/lib/alula/plugins.rb +0 -23
- data/lib/alula/plugins/assets.rb +0 -82
- data/lib/alula/plugins/pagination.rb +0 -121
- data/lib/alula/rake_tasks.rb +0 -42
- data/lib/alula/tasks.rb +0 -2
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require 'alula/contents/post'
|
|
2
|
+
require 'alula/contents/page'
|
|
3
|
+
require 'alula/contents/attachment'
|
|
4
|
+
|
|
5
|
+
module Alula
|
|
6
|
+
class Content
|
|
7
|
+
attr_reader :pages
|
|
8
|
+
attr_reader :posts
|
|
9
|
+
attr_reader :attachments
|
|
10
|
+
attr_reader :statics
|
|
11
|
+
|
|
12
|
+
def initialize(opts = {})
|
|
13
|
+
@site = opts.delete(:site)
|
|
14
|
+
|
|
15
|
+
@pages = []
|
|
16
|
+
@posts = []
|
|
17
|
+
@attachments = []
|
|
18
|
+
@statics = []
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Load our site content
|
|
22
|
+
def load
|
|
23
|
+
# Load everything we can have
|
|
24
|
+
read_content(:posts, :pages, :attachments, :statics)
|
|
25
|
+
|
|
26
|
+
# Generate our dynamic content (pages, categories, archives, etc. etc.)
|
|
27
|
+
generate_content
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def by_name(name)
|
|
31
|
+
(self.pages + self.posts + self.attachments).each do |item|
|
|
32
|
+
return item if item.name == name
|
|
33
|
+
end
|
|
34
|
+
nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def by_slug(slug)
|
|
38
|
+
(self.pages + self.posts + self.attachments).each do |item|
|
|
39
|
+
return item if item.slug == slug
|
|
40
|
+
end
|
|
41
|
+
nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
def read_content(*types)
|
|
46
|
+
@@lock = Mutex.new
|
|
47
|
+
# Load all posts if requested
|
|
48
|
+
if (types.include?(:posts))
|
|
49
|
+
# Read posts
|
|
50
|
+
@site.progress.create :load_posts, title: "Loading posts", total: @site.storage.posts.count
|
|
51
|
+
@site.progress.display
|
|
52
|
+
@site.storage.posts.each do |item|
|
|
53
|
+
name, entry = item
|
|
54
|
+
post = Post.load(item: entry, site: @site)
|
|
55
|
+
@posts << post unless post.nil?
|
|
56
|
+
@@lock.synchronize { @site.progress.step :load_posts }
|
|
57
|
+
end
|
|
58
|
+
# Sort
|
|
59
|
+
@posts.sort!.reverse!
|
|
60
|
+
@site.progress.finish :load_posts
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Load all pages if requested
|
|
64
|
+
if (types.include?(:pages))
|
|
65
|
+
@site.progress.create :load_pages, title: "Loading pages", total: @site.storage.pages.count
|
|
66
|
+
@site.progress.display
|
|
67
|
+
|
|
68
|
+
@site.storage.pages.each do |item|
|
|
69
|
+
name, entry = item
|
|
70
|
+
page = Page.load(item: entry, site: @site)
|
|
71
|
+
@pages << page unless page.nil?
|
|
72
|
+
|
|
73
|
+
@@lock.synchronize { @site.progress.step :load_pages }
|
|
74
|
+
end
|
|
75
|
+
@pages.sort!
|
|
76
|
+
@site.progress.finish :load_pages
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Load all pages if requested
|
|
80
|
+
if (types.include?(:attachments))
|
|
81
|
+
@site.progress.create :load_attachments, title: "Loading attachments", total: @site.storage.attachments.count
|
|
82
|
+
@site.progress.display
|
|
83
|
+
|
|
84
|
+
@site.storage.attachments.each do |item|
|
|
85
|
+
name, entry = item
|
|
86
|
+
attachment = Attachment.load(item: entry, site: @site)
|
|
87
|
+
@attachments << attachment unless attachment.nil?
|
|
88
|
+
|
|
89
|
+
@@lock.synchronize { @site.progress.step :load_attachments }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
@site.progress.finish :load_attachments
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Load all statics
|
|
96
|
+
if (types.include?(:statics))
|
|
97
|
+
@site.storage.statics.each do |name, entry|
|
|
98
|
+
@statics << entry
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def generate_content
|
|
104
|
+
@site.config.generators.each do |type, options|
|
|
105
|
+
|
|
106
|
+
generator = Alula::Generator.load(type: type, options: options, site: @site)
|
|
107
|
+
if generator
|
|
108
|
+
generator.generate
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
require 'alula/contents/metadata'
|
|
2
|
+
require 'alula/core_ext'
|
|
3
|
+
require 'liquid'
|
|
4
|
+
require 'kramdown'
|
|
5
|
+
require 'stringex'
|
|
6
|
+
require 'shellwords'
|
|
7
|
+
require 'htmlentities'
|
|
8
|
+
|
|
9
|
+
module Alula
|
|
10
|
+
class Content
|
|
11
|
+
class Item
|
|
12
|
+
# Instance variables, internal
|
|
13
|
+
# @source :: raw source from file, liquid + markdown
|
|
14
|
+
# @markdown :: parsed liquid, only markdown
|
|
15
|
+
# @body :: parsed markdown, raw content without layout
|
|
16
|
+
# @content :: rendered content, using view, without layout
|
|
17
|
+
|
|
18
|
+
# Metadata, contains all informative data for item
|
|
19
|
+
attr_reader :metadata
|
|
20
|
+
|
|
21
|
+
attr_reader :name
|
|
22
|
+
attr_reader :site
|
|
23
|
+
|
|
24
|
+
attr_accessor :navigation
|
|
25
|
+
|
|
26
|
+
def self.has_payload
|
|
27
|
+
class_variable_set(:@@payload, true)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.has_payload?
|
|
31
|
+
class_variable_defined?(:@@payload) && class_variable_get(:@@payload)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def has_payload?
|
|
35
|
+
self.class.has_payload?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.load(opts = {})
|
|
39
|
+
# Just return nil right away if we have no item
|
|
40
|
+
return nil if opts[:item].nil?
|
|
41
|
+
|
|
42
|
+
# Return nothing if file is not regular file
|
|
43
|
+
return nil unless opts[:item].exists?
|
|
44
|
+
|
|
45
|
+
# If payload is required by class and file doesn't contain it, just skip it
|
|
46
|
+
return nil if has_payload? && !opts[:item].has_payload?
|
|
47
|
+
|
|
48
|
+
# All ok
|
|
49
|
+
return self.new(opts)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def initialize(opts = {}, hooks = {})
|
|
53
|
+
@site = opts.delete(:site)
|
|
54
|
+
@item = opts.delete(:item)
|
|
55
|
+
@name = opts.delete(:name) || @item.name
|
|
56
|
+
|
|
57
|
+
# Set up method overrides
|
|
58
|
+
@hooks = hooks
|
|
59
|
+
# hooks.each do |name, impl|
|
|
60
|
+
# self.class.send(:define_method, name, &impl)
|
|
61
|
+
# end
|
|
62
|
+
|
|
63
|
+
@url = {}
|
|
64
|
+
@path = {}
|
|
65
|
+
@ids = {}
|
|
66
|
+
@navigation = {}
|
|
67
|
+
@substitutes = {}
|
|
68
|
+
@sidebar = {}
|
|
69
|
+
|
|
70
|
+
# Initialize content variables
|
|
71
|
+
flush
|
|
72
|
+
|
|
73
|
+
# Initialize metadata
|
|
74
|
+
@metadata = Metadata.new({
|
|
75
|
+
# Defaults
|
|
76
|
+
date: Time.new(0),
|
|
77
|
+
pin: 500, # Default sorting pin
|
|
78
|
+
layout: 'default',
|
|
79
|
+
view: (self.class.to_s == "Alula::Content::Page" ? "page" : "post"),
|
|
80
|
+
|
|
81
|
+
# Utilities
|
|
82
|
+
base_locale: @site.config.locale,
|
|
83
|
+
environment: @site.config.environment,
|
|
84
|
+
|
|
85
|
+
last_modified: _last_modified,
|
|
86
|
+
generator: nil,
|
|
87
|
+
}.merge(opts))
|
|
88
|
+
|
|
89
|
+
if /^((?<date>(?:\d+-\d+-\d+))-)?(?<slug>(?:.*))(?<extension>(?:\.[^.]+))$/ =~ @name
|
|
90
|
+
@metadata.date = Time.parse(date) unless date.nil? rescue @metadata.date
|
|
91
|
+
@metadata.slug = slug unless slug.nil?
|
|
92
|
+
@metadata.extension = extension unless extension.nil?
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# If payload requested, read it
|
|
96
|
+
read_payload if has_payload?
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Functionality, existence
|
|
100
|
+
def exists?
|
|
101
|
+
@item.exists?
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def extension
|
|
105
|
+
@item.extension
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def filepath
|
|
109
|
+
@item.filepath
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Sorting
|
|
113
|
+
def <=>(other)
|
|
114
|
+
# Sort by date
|
|
115
|
+
cmp = self.date <=> other.date
|
|
116
|
+
|
|
117
|
+
# Sort by pinning, smaller marks higher in the list
|
|
118
|
+
cmp == 0 and cmp = self.metadata.pin <=> other.metadata.pin
|
|
119
|
+
|
|
120
|
+
# Sort by slug name alphabetically
|
|
121
|
+
cmp == 0 and cmp = self.slug <=> other.slug
|
|
122
|
+
|
|
123
|
+
cmp
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Renders actual content of itm using current layout
|
|
127
|
+
# This handles all locales automatically
|
|
128
|
+
def render(locale)
|
|
129
|
+
@content[locale] ||= begin
|
|
130
|
+
_old_locale = self.current_locale
|
|
131
|
+
self.current_locale = locale
|
|
132
|
+
|
|
133
|
+
# Flush if we have generator
|
|
134
|
+
if @hooks[:render]
|
|
135
|
+
instance_exec(locale, &@hooks[:render])
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Make sure our content is parsed
|
|
139
|
+
parse_liquid(locale)
|
|
140
|
+
parse_markdown(locale)
|
|
141
|
+
|
|
142
|
+
self.view.render(item: self, content: self.body(locale), locale: locale)
|
|
143
|
+
ensure
|
|
144
|
+
self.current_locale = _old_locale
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def write
|
|
149
|
+
# Write all languages
|
|
150
|
+
languages = self.metadata.languages || [self.site.config.locale]
|
|
151
|
+
|
|
152
|
+
languages.each do |locale|
|
|
153
|
+
begin
|
|
154
|
+
_old_locale = self.current_locale
|
|
155
|
+
self.current_locale = locale
|
|
156
|
+
|
|
157
|
+
# Render our content
|
|
158
|
+
self.render(locale)
|
|
159
|
+
|
|
160
|
+
output = self.layout.render(item: self, locale: locale) do
|
|
161
|
+
self.content(locale)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Filter output
|
|
165
|
+
self.site.filters.each do |name, filter|
|
|
166
|
+
output = filter.output(output, locale) if filter.respond_to?(:output)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Write content to file
|
|
170
|
+
@site.storage.output_public(self.path(locale)) do
|
|
171
|
+
self.site.compressors.html.compress(output)
|
|
172
|
+
end
|
|
173
|
+
ensure
|
|
174
|
+
self.current_locale = _old_locale
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Layout engine
|
|
180
|
+
def layout
|
|
181
|
+
@layout ||= @site.theme.layout(self.metadata.layout)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def view
|
|
185
|
+
@view ||= @site.theme.view(self.metadata.view)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Accessors
|
|
189
|
+
def current_locale
|
|
190
|
+
@@current_locale ||= nil
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def current_locale=(newLocale)
|
|
194
|
+
@@current_locale = newLocale
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def content(locale = nil)
|
|
198
|
+
@content[(locale || self.current_locale || self.site.config.locale)] ||= begin
|
|
199
|
+
render(locale)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def body(locale = nil)
|
|
204
|
+
@body[(locale || self.current_locale || self.site.config.locale)] ||= begin
|
|
205
|
+
parse_markdown(locale)
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def markdown(locale = nil)
|
|
210
|
+
@markdown[(locale || self.current_locale || self.site.config.locale)] ||= begin
|
|
211
|
+
parse_liquid(locale)
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def sidebar(locale = nil)
|
|
216
|
+
locale ||= self.current_locale || self.site.config.locale
|
|
217
|
+
@sidebar[locale] ||= begin
|
|
218
|
+
items = self.site.config.content.sidebar.collect do |item|
|
|
219
|
+
case item
|
|
220
|
+
when :pages
|
|
221
|
+
self.site.content.pages.select{|p| p.generator.nil? and p.languages.include?(locale) }
|
|
222
|
+
when :languages
|
|
223
|
+
languages
|
|
224
|
+
.reject{|lang| lang == locale}
|
|
225
|
+
.collect{|lang| Hashie::Mash.new({url: url(lang), title: I18n.t('language_name', locale: lang)}) }
|
|
226
|
+
else
|
|
227
|
+
@content.by_slug(self.config.index)
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
items.flatten.select {|i| !i.nil?}
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def url(locale = nil)
|
|
235
|
+
locale ||= self.current_locale || self.site.config.locale
|
|
236
|
+
@url[locale] ||= begin
|
|
237
|
+
url = if @metadata.permalink(locale)
|
|
238
|
+
@metadata.permalink(locale)
|
|
239
|
+
else
|
|
240
|
+
template = @metadata.template || (self.class.to_s == "Alula::Content::Page" ? @site.config.pagelinks : @site.config.permalinks)
|
|
241
|
+
self.substitutes(locale).inject(template) { |result, token|
|
|
242
|
+
result.gsub(/:#{Regexp.escape token.first}/, token.last)
|
|
243
|
+
}.gsub(/\/\//, '/')
|
|
244
|
+
end
|
|
245
|
+
# Add .html only if we don't have extension already
|
|
246
|
+
if ::File.extname(url).empty?
|
|
247
|
+
url += ".html" unless url[/\/$/] and ::File.extname(url).empty?
|
|
248
|
+
end
|
|
249
|
+
url
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def id(locale = nil)
|
|
254
|
+
@ids[(locale || self.current_locale || self.site.config.locale)] ||= self.url(locale)
|
|
255
|
+
.gsub(/\.\S+$/, '')
|
|
256
|
+
.gsub(/[\/]/, ' ')
|
|
257
|
+
.to_url
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def path(locale = nil)
|
|
261
|
+
locale ||= self.current_locale || self.site.config.locale
|
|
262
|
+
@path[locale] ||= begin
|
|
263
|
+
path = ::File.join(CGI.unescape(self.url(locale)))
|
|
264
|
+
path = ::File.join(path, "index.html") unless path[/\/$/].nil?
|
|
265
|
+
path
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def previous(locale = nil)
|
|
270
|
+
if @hooks[:previous]
|
|
271
|
+
instance_exec(locale, &@hooks[:previous])
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def next(locale = nil)
|
|
276
|
+
if @hooks[:next]
|
|
277
|
+
instance_exec(locale, &@hooks[:next])
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def navigation(locale = nil)
|
|
282
|
+
if @hooks[:navigation]
|
|
283
|
+
instance_exec(locale, &@hooks[:navigation])
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
#
|
|
288
|
+
# Resets all cached variables and languages etc.
|
|
289
|
+
def flush
|
|
290
|
+
flush_render
|
|
291
|
+
@markdown = {}
|
|
292
|
+
@body = {}
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def flush_render
|
|
296
|
+
# Initialize current locale
|
|
297
|
+
self.current_locale ||= nil
|
|
298
|
+
@content = {}
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
# Proxy to metadata
|
|
302
|
+
def method_missing(meth, *args, &blk)
|
|
303
|
+
# Proxy to metadata
|
|
304
|
+
if !meth[/=$/] and metadata.respond_to?(meth)
|
|
305
|
+
# Invalidate some attributes depending on this
|
|
306
|
+
if %w{template name slug}.include?(meth[0..-2])
|
|
307
|
+
var = instance_variable_get("@#{meth[0..-2]}")
|
|
308
|
+
instance_variable_set("@#{meth[0..2]}", var.class.new)
|
|
309
|
+
end
|
|
310
|
+
args.unshift(self.current_locale || @site.config.locale) if args.empty?
|
|
311
|
+
metadata.send(meth, *args)
|
|
312
|
+
else
|
|
313
|
+
super
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# Substitues for URL
|
|
318
|
+
def substitutes(locale = nil)
|
|
319
|
+
locale ||= self.current_locale || self.site.config.locale
|
|
320
|
+
|
|
321
|
+
@substitutes[locale] ||= begin
|
|
322
|
+
subs = {
|
|
323
|
+
"year" => @metadata.date.strftime('%Y'),
|
|
324
|
+
"month" => @metadata.date.strftime('%m'),
|
|
325
|
+
"day" => @metadata.date.strftime('%d'),
|
|
326
|
+
"locale" => (@site.config.locale == locale && @site.config.hides_base_locale ? "" : locale),
|
|
327
|
+
"name" => CGI.escape(name).gsub('%2F', '/'),
|
|
328
|
+
"slug" => CGI.escape(@metadata.slug(locale)).gsub('%2F', '/'),
|
|
329
|
+
"title" => @metadata.title(locale).to_url,
|
|
330
|
+
}
|
|
331
|
+
if self.metadata.generator
|
|
332
|
+
subs.merge!(self.metadata.generator.substitutes(locale, self))
|
|
333
|
+
end
|
|
334
|
+
subs
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
private
|
|
339
|
+
def _last_modified
|
|
340
|
+
if @hooks[:last_modified]
|
|
341
|
+
return instance_exec(locale, &@hooks[:next])
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
return unless self.class.to_s[/Page|Post/]
|
|
345
|
+
mtime = nil
|
|
346
|
+
unless @item.nil?
|
|
347
|
+
mtime = @item.mtime
|
|
348
|
+
if self.site.git
|
|
349
|
+
rev = %x{git rev-list -n 1 HEAD #{Shellwords.escape(@item.filepath)}}.strip
|
|
350
|
+
time = %x{git show --pretty=format:%ai --abbrev-commit #{rev}|head -1}.strip
|
|
351
|
+
mtime = Time.parse(time) rescue nil
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
mtime
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
def read_payload
|
|
358
|
+
# Do not read directly to instance variable as we know there is payload
|
|
359
|
+
return if @item.nil?
|
|
360
|
+
|
|
361
|
+
# source = File.read(@file)
|
|
362
|
+
source = @item.read
|
|
363
|
+
if /^(?<manifest>(?:---\s*\n.*?\n?)^(---\s*$\n?))(?<source>.*)/m =~ source
|
|
364
|
+
@source = source
|
|
365
|
+
@metadata.load(manifest)
|
|
366
|
+
end
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
def parse_liquid(locale)
|
|
370
|
+
@markdown[locale] ||= begin
|
|
371
|
+
begin
|
|
372
|
+
_old_locale = @site.context.locale
|
|
373
|
+
_old_item = @site.context.item
|
|
374
|
+
@site.context.locale = locale
|
|
375
|
+
@site.context.item = self
|
|
376
|
+
Liquid::Template.parse(@source).render(@site.context.to_liquid)
|
|
377
|
+
ensure
|
|
378
|
+
@site.context.locale = _old_locale
|
|
379
|
+
@site.context.item = _old_item
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def parse_markdown(locale)
|
|
385
|
+
@body[locale] ||= begin
|
|
386
|
+
coder = HTMLEntities.new
|
|
387
|
+
quotes = %w{single.left single.right double.left double.right}.collect {|q|
|
|
388
|
+
coder.encode(I18n.t("quotes.#{q}", locale: locale), :decimal).gsub(/&#(\d+);/, '\1')
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
body = Kramdown::Document.new(markdown(locale), {
|
|
392
|
+
auto_ids: false,
|
|
393
|
+
footnote_nr: 1,
|
|
394
|
+
entity_output: 'as_char',
|
|
395
|
+
html_to_native: true,
|
|
396
|
+
toc_levels: '1..6',
|
|
397
|
+
smart_quotes: quotes,
|
|
398
|
+
}).to_html
|
|
399
|
+
|
|
400
|
+
self.site.filters.each do |name, filter|
|
|
401
|
+
body = filter.process(body, locale) if filter.respond_to?(:process)
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
body
|
|
405
|
+
end
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
end
|