octopress-ink 1.0.0.rc.48 → 1.0.0.rc.49

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d6ba7aa056db45f2f28d8b70afaf07a0401b11e5
4
- data.tar.gz: ee19501a664e330bc5674982382f8b0025686be6
3
+ metadata.gz: a4858b7de639dfc2e080960481b60d2e3b35c809
4
+ data.tar.gz: 748629f2f8af0d24a45fe78025106eb9c6cd4b57
5
5
  SHA512:
6
- metadata.gz: d9b3d41581565613c6757e42581bbe398d1463ceea58a3fc85a651b3ba064ad3bfe826e37f2c072fe29540142534903528af59162ea619c2f764ee8d93a96c68
7
- data.tar.gz: 7165df6396ecf13537da89780ef11e1b94862bfa7bf1f1a6309f27ff4a9aa5383c5f7165858fcb7d667cdcbcb5543759ae6be81eac77118761393ea49092230c
6
+ metadata.gz: 71f5e690c1ca468c8e14f8ab3770cc53b0fb2cfecf7379ca4be5ca11106de7a61acc46172571e69bfcc9bdc5e14b98427f236e198d91f19d92355b69f84c360b
7
+ data.tar.gz: 329f7932850c832ced252c2fd5103c45c9965c78528d4aee906bb303f919b9858b58c350c53407bc2c86375bc9328160fa0b5e500f6ca448dc7ba10011ac1acf
data/CHANGELOG.md CHANGED
@@ -1,6 +1,25 @@
1
1
  # Changelog
2
2
 
3
- ### 1.0.0 RC47 - 2015-02-18
3
+ ### 1.0.0 RC49 - 2015-03-02
4
+
5
+ - New: Plugin bootstrap allows plugins to work with templates for post indexes and RSS feeds. Each with automatic support for multilingual sites.
6
+
7
+ Plugins can add pages and templates for:
8
+ - A post index
9
+ - A post archive
10
+ - A post RSS feed
11
+ - A link posts RSS feed (with octopress-linkblog)
12
+ - An articles RSS feed (with octopress-linkblog)
13
+ - A post RSS feed
14
+ - Category index pages
15
+ - Tag index pages
16
+ - Category RSS feeds
17
+ - Tag RSS feeds
18
+
19
+ The plugin bootstrap will automatically handle page titles, permalinks and generating multiple pages for each tag and category.
20
+ If a user installs octopress-multilingual, all pages will be replicated and filtered for each language.
21
+
22
+ ### 1.0.0 RC48 - 2015-02-18
4
23
  - Minor: Improved template asset info when listed with `octopress ink list [plugin]` command.
5
24
 
6
25
  ### 1.0.0 RC47 - 2015-02-18
data/lib/octopress-ink.rb CHANGED
@@ -15,17 +15,18 @@ require 'octopress-ink/cache'
15
15
 
16
16
  module Octopress
17
17
  module Ink
18
+ extend self
18
19
 
19
20
  autoload :Utils, 'octopress-ink/utils'
20
21
  autoload :Assets, 'octopress-ink/assets'
21
22
  autoload :Convertible, 'octopress-ink/jekyll/convertible'
22
23
  autoload :Page, 'octopress-ink/jekyll/page'
23
- autoload :TemplatePage, 'octopress-ink/jekyll/template_page'
24
24
  autoload :Layout, 'octopress-ink/jekyll/layout'
25
25
  autoload :StaticFile, 'octopress-ink/jekyll/static_file'
26
26
  autoload :StaticFileContent, 'octopress-ink/jekyll/static_file_content'
27
27
  autoload :Plugins, 'octopress-ink/plugins'
28
28
  autoload :Plugin, 'octopress-ink/plugin'
29
+ autoload :Bootstrap, 'octopress-ink/plugin/bootstrap'
29
30
  autoload :PluginAssetPipeline, 'octopress-ink/plugin_asset_pipeline'
30
31
  autoload :Tags, 'octopress-ink/tags'
31
32
 
@@ -38,7 +39,7 @@ module Octopress
38
39
 
39
40
  Plugins.reset
40
41
 
41
- def self.version
42
+ def version
42
43
  version = "Jekyll v#{Jekyll::VERSION}, "
43
44
  if defined? Octopress::VERSION
44
45
  version << "Octopress v#{Octopress::VERSION} "
@@ -46,7 +47,7 @@ module Octopress
46
47
  version << "Octopress Ink v#{Octopress::Ink::VERSION}"
47
48
  end
48
49
 
49
- def self.payload(lang=nil)
50
+ def payload(lang=nil)
50
51
  config = Plugins.config(lang)
51
52
  ink_payload = {
52
53
  'plugins' => config['plugins'],
@@ -59,11 +60,11 @@ module Octopress
59
60
  ink_payload
60
61
  end
61
62
 
62
- def self.enabled?
63
+ def enabled?
63
64
  @load_plugin_assets
64
65
  end
65
66
 
66
- def self.load_plugin_assets=(setting)
67
+ def load_plugin_assets=(setting)
67
68
  @load_plguin_assets = setting
68
69
  end
69
70
 
@@ -71,7 +72,12 @@ module Octopress
71
72
  #
72
73
  # plugin - A subclass of Plugin
73
74
  #
74
- def self.register_plugin(plugin, options={})
75
+ def register_plugin(plugin, options={})
76
+ Plugins.register_plugin(plugin, options)
77
+ end
78
+
79
+ def register_theme(plugin, options={})
80
+ options['type'] = 'theme'
75
81
  Plugins.register_plugin(plugin, options)
76
82
  end
77
83
 
@@ -79,23 +85,27 @@ module Octopress
79
85
  #
80
86
  # options - A hash of configuration options.
81
87
  #
82
- def self.add_plugin(options={})
83
- Plugins.register_plugin Plugin, options
88
+ def add_plugin(options={})
89
+ register_plugin Plugin, options
90
+ end
91
+
92
+ def add_theme(options={})
93
+ register_theme Plugin, options
84
94
  end
85
95
 
86
- def self.add_docs(options={})
96
+ def add_docs(options={})
87
97
  Docs.register_docs options
88
98
  end
89
99
 
90
- def self.config
100
+ def config
91
101
  @config ||= Configuration.config
92
102
  end
93
103
 
94
- def self.plugins
104
+ def plugins
95
105
  Plugins.plugins
96
106
  end
97
107
 
98
- def self.plugin(name)
108
+ def plugin(name)
99
109
  begin
100
110
  Plugins.plugin(name)
101
111
  rescue
@@ -112,7 +122,7 @@ module Octopress
112
122
  # but no assets, i.e. 'minimal' info.
113
123
  #
114
124
  #
115
- def self.list(options={})
125
+ def list(options={})
116
126
  site = Octopress.site(options)
117
127
  Plugins.register
118
128
  options = {'minimal'=>true} if options.empty?
@@ -128,7 +138,7 @@ module Octopress
128
138
  puts message
129
139
  end
130
140
 
131
- def self.plugin_list(name, options)
141
+ def plugin_list(name, options)
132
142
  config = options.delete('config') # Jekyll conflicts with this option
133
143
  Octopress.site(options)
134
144
  Octopress.site.read
@@ -142,7 +152,7 @@ module Octopress
142
152
  end
143
153
  end
144
154
 
145
- def self.copy_plugin_assets(name, options)
155
+ def copy_plugin_assets(name, options)
146
156
  config = options.delete('config') # Jekyll conflicts with this option
147
157
  Octopress.site(options)
148
158
  Plugins.register
@@ -162,7 +172,7 @@ module Octopress
162
172
  end
163
173
  end
164
174
 
165
- def self.copy_path(name, options)
175
+ def copy_path(name, options)
166
176
  if path = options.delete('path')
167
177
  full_path = File.join(Dir.pwd, path)
168
178
  if !Dir["#{full_path}/*"].empty? && options['force'].nil?
@@ -175,7 +185,7 @@ module Octopress
175
185
  full_path
176
186
  end
177
187
 
178
- def self.list_plugins(options={})
188
+ def list_plugins(options={})
179
189
  Octopress.site(options)
180
190
  Plugins.register
181
191
  puts "\nCurrently installed plugins:"
@@ -186,7 +196,7 @@ module Octopress
186
196
  end
187
197
  end
188
198
 
189
- def self.gem_dir(*subdirs)
199
+ def gem_dir(*subdirs)
190
200
  File.expand_path(File.join(File.dirname(__FILE__), '../', *subdirs))
191
201
  end
192
202
 
@@ -196,7 +206,7 @@ module Octopress
196
206
  # Usage: In rakefile require 'octopress-ink'
197
207
  # then add task calling Octopress::Ink.copy_doc for each file
198
208
  #
199
- def self.copy_doc(source, dest, permalink=nil)
209
+ def copy_doc(source, dest, permalink=nil)
200
210
  contents = File.open(source).read
201
211
 
202
212
  # Convert H1 to title and add permalink in YAML front-matter
@@ -210,12 +220,12 @@ module Octopress
210
220
 
211
221
  private
212
222
 
213
- def self.not_found(plugin)
223
+ def not_found(plugin)
214
224
  puts "Plugin '#{plugin}' not found."
215
225
  list_plugins
216
226
  end
217
227
 
218
- def self.doc_yaml(title, permalink)
228
+ def doc_yaml(title, permalink)
219
229
  yaml = "---\n"
220
230
  yaml += "title: \"#{title.strip}\"\n"
221
231
  yaml += "permalink: #{permalink.strip}\n" if permalink
@@ -226,6 +236,12 @@ end
226
236
 
227
237
  Liquid::Template.register_tag('css_asset_tag', Octopress::Ink::Tags::StylesheetTag)
228
238
  Liquid::Template.register_tag('js_asset_tag', Octopress::Ink::Tags::JavascriptTag)
239
+ Liquid::Template.register_tag('categories', Octopress::Ink::Tags::CategoryTag)
240
+ Liquid::Template.register_tag('category_list', Octopress::Ink::Tags::CategoryTag)
241
+ Liquid::Template.register_tag('tags', Octopress::Ink::Tags::CategoryTag)
242
+ Liquid::Template.register_tag('tag_list', Octopress::Ink::Tags::CategoryTag)
243
+ Liquid::Template.register_tag('feeds', Octopress::Ink::Tags::FeedsTag)
244
+ Liquid::Template.register_tag('feed_updated', Octopress::Ink::Tags::FeedUpdatedTag)
229
245
 
230
246
  Octopress::Docs.add({
231
247
  name: "Octopress Ink",
@@ -2,10 +2,11 @@ module Octopress
2
2
  module Ink
3
3
  module Assets
4
4
  class Asset
5
- attr_reader :plugin, :dir, :base, :root, :file
5
+ attr_reader :plugin, :dir, :base, :root, :file, :overridden
6
6
  attr_accessor :exists
7
7
 
8
8
  FRONT_MATTER = /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m
9
+ @overridden = false
9
10
 
10
11
  def initialize(plugin, base, file)
11
12
  @file = file
@@ -19,13 +20,13 @@ module Octopress
19
20
 
20
21
  def info
21
22
  message = filename.ljust(35)
22
- if disabled?
23
+ if @overridden
24
+ message += "-overridden by #{@overridden}-"
25
+ elsif disabled?
23
26
  message += "-disabled-"
24
- elsif self.respond_to?(:url_info)
25
- message += url_info
26
27
  elsif path.to_s != plugin_path
27
28
  shortpath = File.join(Plugins.custom_dir.sub(Dir.pwd,''), dir).sub('/','')
28
- message += "from: #{shortpath}/#{filename}"
29
+ message += "from: #{File.join(shortpath,filename).sub('/./', '/')}"
29
30
  end
30
31
  " - #{message}"
31
32
  end
@@ -35,7 +36,7 @@ module Octopress
35
36
  end
36
37
 
37
38
  def disabled?
38
- is_disabled(base, filename)
39
+ is_disabled(base, filename) || @overridden
39
40
  end
40
41
 
41
42
  def is_disabled(base, file)
@@ -43,6 +44,10 @@ module Octopress
43
44
  config.include?(base) || config.include?(File.join(base, filename))
44
45
  end
45
46
 
47
+ def override(plugin)
48
+ @overridden = plugin.name
49
+ end
50
+
46
51
  def path
47
52
  if @found_file
48
53
  @found_file
@@ -6,7 +6,7 @@ module Octopress
6
6
  module Assets
7
7
  class PageAsset < Asset
8
8
  attr_reader :filename
9
- attr_accessor :data, :permalink_name
9
+ attr_accessor :data, :permalink_name, :cloned, :clone_of
10
10
 
11
11
  def initialize(plugin, base, file)
12
12
  @root = plugin.assets_path
@@ -27,20 +27,24 @@ module Octopress
27
27
  if page.url && !find_page(page)
28
28
  Octopress.site.pages << page
29
29
  plugin.config['permalinks'] ||= {}
30
- plugin.config['permalinks'][@permalink_name] ||= page.url
30
+ permalink_config ||= page.url
31
31
  end
32
32
  end
33
33
 
34
- def clone(permalink, permalink_name=nil)
34
+ def clone(data={})
35
+ self.cloned = true
35
36
  p = PageAsset.new(plugin, base, file)
36
- p.permalink_name = permalink_name
37
- p.permalink ||= permalink
37
+ p.clone_of = self
38
+ p.data = data
38
39
  p
39
40
  end
40
41
 
41
42
  def merge_data(data={})
42
- self.data.merge!(data)
43
- self
43
+ page.data.merge!(data)
44
+ end
45
+
46
+ def deep_merge(data={})
47
+ Jekyll::Utils.deep_merge_hashes(page.data, data)
44
48
  end
45
49
 
46
50
  def find_page(page)
@@ -55,25 +59,59 @@ module Octopress
55
59
 
56
60
  def page
57
61
  @page ||= begin
58
- page = Page.new(Octopress.site, source_dir, page_dir, file, self)
62
+ page = Page.new(Octopress.site, source_dir, page_dir, file)
63
+
64
+ if permalink_config
65
+ page.data['permalink'] = permalink_config
66
+ else
67
+ permalink = page.data['permalink']
68
+ end
69
+
59
70
  page.data.merge!(@data)
71
+
60
72
  page
61
73
  end
62
74
  end
63
75
 
64
76
  def info
65
77
  message = super
66
- name = permalink_name << page.ext
67
- message.sub!(/#{filename}\s*/, name.ljust(35))
68
- message.ljust(25) << (permalink || page.permalink || '')
78
+ return message if disabled?
79
+
80
+ if clone_of
81
+ " #{permalink}"
82
+ elsif cloned
83
+ message << "\n #{permalink}"
84
+ else
85
+ name = permalink_name << page.ext
86
+ message.sub!(/#{filename}\s*/, name.ljust(35))
87
+ message.ljust(25) << permalink
88
+ end
69
89
  end
70
90
 
71
91
  def permalink
72
- @permalink ||= plugin.config['permalinks'][permalink_name]
92
+ page.url
93
+ end
94
+
95
+ def url; permalink; end
96
+
97
+ def lang
98
+ data['lang']
73
99
  end
74
100
 
75
101
  def permalink=(url)
76
- @permalink = url
102
+ page.data['permalink'] = url
103
+ permalink_config = url
104
+ end
105
+
106
+ def permalink_config
107
+ if Octopress.multilingual? && lang
108
+ plugin.config(lang)['permalinks'][permalink_name]
109
+ else
110
+ plugin.config['permalinks'][permalink_name]
111
+ end
112
+ end
113
+
114
+ def permalink_config=(url)
77
115
  if permalink_name
78
116
  plugin.config['permalinks'][permalink_name] = url
79
117
  end
@@ -24,30 +24,20 @@ module Octopress
24
24
  message = " - #{message}\n"
25
25
 
26
26
  self.pages.each do |page|
27
- message << " /#{page.path.sub('index.html', '')}\n"
27
+ message << " #{page.url}\n"
28
28
  end
29
29
  message
30
30
  end
31
31
 
32
- def new_page(permalink, data={})
32
+ def new_page(data={})
33
33
  return if disabled?
34
-
35
- dir = File.dirname(permalink)
36
- name = File.basename(permalink)
37
-
38
- page = Ink::TemplatePage.new(Octopress.site, File.dirname(self.path), '.', File.basename(self.path))
39
-
34
+ page = Ink::Page.new(Octopress.site, File.dirname(self.path), '.', File.basename(self.path))
40
35
  page.data.merge!(data)
41
36
 
42
- page.dir = dir
43
- page.name = name
44
- page.process(name)
45
-
46
37
  self.pages << page
47
38
 
48
39
  page
49
40
  end
50
-
51
41
  end
52
42
  end
53
43
  end
@@ -7,6 +7,7 @@ module Octopress
7
7
  c.option "layouts", "--layouts", "#{action} only layouts"
8
8
  c.option "includes", "--includes", "#{action} only includes"
9
9
  c.option "pages", "--pages", "#{action} only pages"
10
+ c.option "templates", "--templates", "#{action} only pages"
10
11
  c.option "stylesheets", "--stylesheets", "#{action} only Stylesheets (.css, .scss, .sass)"
11
12
  c.option "css", "--css", "#{action} only CSS files (.css)"
12
13
  c.option "sass", "--sass", "#{action} only Sass files (.scss, .sass)"
@@ -2,27 +2,7 @@ module Octopress
2
2
  module Ink
3
3
  class Page < Jekyll::Page
4
4
  include Ink::Convertible
5
- attr_reader :asset, :plugin
6
-
7
- # Purpose: Configs can override a page's permalink
8
- #
9
- # url - Path relative to destination directory.
10
- # examples:
11
- # - '/' for the _site/index.html page
12
- # - '/archive/' for the _site/archive/index.html page
13
- #
14
- def initialize(site, base, dir, name, asset)
15
- @asset = asset
16
- @plugin = asset.plugin
17
- super(site, base, dir, name)
18
- end
19
-
20
- def destination(dest)
21
- unless @dest
22
- @dest = File.join(dest, self.url)
23
- end
24
- @dest
25
- end
5
+ attr_accessor :dir, :name
26
6
 
27
7
  def relative_asset_path
28
8
  site_source = Pathname.new Octopress.site.source
@@ -34,9 +14,6 @@ module Octopress
34
14
  #
35
15
  def url
36
16
  @url ||= begin
37
- @asset.permalink ||= self.data['permalink']
38
- @url = @asset.permalink
39
-
40
17
  super
41
18
 
42
19
  if @url && @url =~ /\/$/
@@ -4,11 +4,14 @@ module Octopress
4
4
  module Ink
5
5
  class Plugin
6
6
 
7
+ include Bootstrap
8
+
7
9
  DEFAULT_CONFIG = {
8
- type: 'plugin'
10
+ type: 'plugin',
11
+ bootstrap: true
9
12
  }
10
13
 
11
- attr_reader :name, :type, :path, :assets_path, :local, :website, :description, :gem, :version, :source_url, :website,
14
+ attr_reader :name, :type, :path, :assets_path, :local, :website, :description, :gem, :version, :source_url, :website, :bootstrap,
12
15
  :layouts_dir, :stylesheets_dir, :javascripts_dir, :files_dir, :includes_dir, :images_dir, :templates_dir,
13
16
  :layouts, :includes, :images, :fonts, :files, :pages, :templates, :docs
14
17
 
@@ -62,11 +65,12 @@ module Octopress
62
65
  add_includes
63
66
  add_layouts
64
67
  add_javascripts
68
+ add_stylesheets
65
69
  add_fonts
66
70
  add_files
67
71
  add_pages
68
72
  add_templates
69
- add_stylesheets
73
+ bootstrap_plugin if @bootstrap
70
74
  end
71
75
  end
72
76
  end
@@ -149,15 +153,17 @@ module Octopress
149
153
  # returns: Hash of merged user and default config.yml files
150
154
  #
151
155
  def config(lang=nil)
152
- @config ||= configs.first.read
153
-
154
156
  if lang
155
- lang_config_hash[lang] || @config
157
+ lang_config_hash[lang] || read_config
156
158
  else
157
- @config
159
+ read_config
158
160
  end
159
161
  end
160
162
 
163
+ def read_config
164
+ @config ||= configs.first.read
165
+ end
166
+
161
167
  # Language configurations
162
168
  #
163
169
  # returns: Hash of configs for files matching: conifg_[lang].yml
@@ -291,9 +297,11 @@ module Octopress
291
297
  case name
292
298
  when 'pages'
293
299
  header = "pages:".ljust(36) + "urls"
294
- message << asset_list(assets, header)
300
+ message << asset_list(assets.sort_by(&:file), header)
295
301
  when 'config-file'
296
- message << asset_list(assets, 'config')
302
+ message << " config:\n"
303
+ message << Ink::Utils.pretty_print_yaml(@config)
304
+ message << "\n"
297
305
 
298
306
  lang_config_hash.keys.each do |lang|
299
307
  message << "\n"
@@ -450,16 +458,19 @@ module Octopress
450
458
  add_template_pages
451
459
  end
452
460
 
453
- def add_template_page(template, permalink, data={})
454
- template = @templates.find { |t| t.filename == template }
455
-
456
- unless template.nil? || template.disabled?
457
- page = template.new_page(permalink, data)
461
+ def add_template_page(template, data={})
462
+ template = find_template(template) if template.is_a? String
463
+ unless template.nil?
464
+ page = template.new_page(data)
458
465
  Octopress.site.pages << page
459
466
  page
460
467
  end
461
468
  end
462
469
 
470
+ def find_template(file)
471
+ @templates.find { |t| t.filename == file }
472
+ end
473
+
463
474
  def add_docs
464
475
  Octopress::Docs.add_plugin_docs(self)
465
476
  end
@@ -0,0 +1,507 @@
1
+ module Octopress
2
+ module Ink
3
+ module Bootstrap
4
+ attr_reader :post_index, :post_archive, :category_index, :tag_index, :main_feed, :category_feed, :tag_feed, :articles_feed, :links_feed
5
+
6
+ # This module gives Plugins the ability to easily offer
7
+ # Index pages, archives, RSS feeds, Category and Tag indexes
8
+ # All with multilingual support.
9
+ #
10
+
11
+ def self.reset
12
+ @pages = {}
13
+ @categories = {}
14
+ @tags = {}
15
+ @feeds = {}
16
+ end
17
+
18
+ def self.pages
19
+ @pages
20
+ end
21
+
22
+ def self.categories
23
+ @categories
24
+ end
25
+
26
+ def self.tags
27
+ @tags
28
+ end
29
+
30
+ def self.feeds
31
+ @feeds
32
+ end
33
+
34
+ def self.page(lang, type, key)
35
+ @pages[type][key]
36
+ end
37
+
38
+ def self.category(category, lang)
39
+ category = "#{category}_#{page.lang}" if Octopress.multilingual? && page.lang
40
+ @categories[category]
41
+ end
42
+
43
+ def self.tag(category, lang)
44
+ tag = "#{tag}_#{page.lang}" if Octopress.multilingual? && page.lang
45
+ @tags[tag]
46
+ end
47
+
48
+ def self.add_page(page, key=nil)
49
+ if @pages[page.url].nil?
50
+ @pages[page.url] = page
51
+
52
+ url = page.url.sub(/index.(xml|html)/, '')
53
+
54
+ if key == 'feeds'
55
+ @feeds[url] = page.data['title']
56
+ elsif key == 'tag'
57
+ tag = page.data[key]
58
+ tag = "#{tag}_#{page.lang}" if Octopress.multilingual? && page.lang
59
+ @tags[tag] = url
60
+ elsif key == 'category'
61
+ category = page.data[key]
62
+ category = "#{category}_#{page.lang}" if Octopress.multilingual? && page.lang
63
+ @categories[category] = url
64
+ end
65
+ page
66
+ end
67
+ end
68
+
69
+ # Generate site pages from bootstrappable pages and templates
70
+ #
71
+ def bootstrap_plugin
72
+ register_templates
73
+ inject_configs
74
+ add_page_metadata
75
+
76
+ # Add pages for other languages
77
+ if Octopress.multilingual?
78
+ Octopress::Multilingual.languages.each { |lang| inject_pages(lang) }
79
+ else
80
+ inject_pages
81
+ end
82
+ end
83
+
84
+ def register_templates
85
+ # Find pages and templates
86
+
87
+ @post_index = pages.find { |p| p.filename == 'post_index.html' }
88
+ @post_archive = pages.find { |p| p.filename == 'post_archive.html' }
89
+ @main_feed = templates.find { |p| p.filename == 'main_feed.xml' }
90
+ @articles_feed = templates.find { |p| p.filename == 'articles_feed.xml' }
91
+ @links_feed = templates.find { |p| p.filename == 'links_feed.xml' }
92
+ @category_index = templates.find { |t| t.filename == 'category_index.html' }
93
+ @tag_index = templates.find { |t| t.filename == 'tag_index.html' }
94
+ @category_feed = templates.find { |t| t.filename == 'category_feed.xml' }
95
+ @tag_feed = templates.find { |t| t.filename == 'tag_feed.xml' }
96
+ end
97
+
98
+ # Merge optional configurations with plugin configuration
99
+ # Plugin configs overrides optional configs
100
+ #
101
+ def inject_configs
102
+ optional_configs.each do |opt_config|
103
+ @config = Jekyll::Utils.deep_merge_hashes(YAML.load(opt_config), @config)
104
+ end
105
+ end
106
+
107
+ # Add default configurations based on matching pages and templates
108
+ #
109
+ def optional_configs
110
+ opt_config = []
111
+ opt_config << post_index_config if post_index
112
+ opt_config << post_archive_config if post_archive
113
+ opt_config << main_feed_config if main_feed
114
+ opt_config << links_feed_config if links_feed
115
+ opt_config << articles_feed_config if articles_feed
116
+ opt_config << category_index_config if category_index
117
+ opt_config << tag_index_config if tag_index
118
+ opt_config << category_feed_config if category_feed
119
+ opt_config << tag_feed_config if tag_feed
120
+
121
+ # Add shared configurations for tags and categories
122
+ #
123
+ opt_config << category_config_defaults if category_index || category_feed
124
+ opt_config << tag_config_defaults if tag_index || tag_feed
125
+
126
+ # Add feed defaults if plugin has any feed pages
127
+ #
128
+ if main_feed || links_feed || articles_feed || category_feed || tag_feed
129
+ opt_config << feed_config_defaults
130
+ end
131
+
132
+ opt_config
133
+ end
134
+
135
+ def add_page_metadata
136
+ [post_index, post_archive].compact.each do |page|
137
+ page.page.data['title'] ||= page_title(page.page, config)
138
+ if Octopress.multilingual?
139
+ page.page.data['lang'] = Octopress.site.config['lang']
140
+ end
141
+
142
+ unless Bootstrap.add_page(page)
143
+ page.override Bootstrap.pages[page.url].plugin
144
+ end
145
+ end
146
+ end
147
+
148
+ # Automatically clone pages or generate templates
149
+ #
150
+ # This will only occur if:
151
+ # - Site configuration warrants it
152
+ # - Plugin assets are present
153
+ #
154
+ # For example:
155
+ # - Index pages are cloned only for additonal languages on multilingual sites
156
+ # - Link-blogging feeds are only generated if the octopress-linkblog plugin is present
157
+ # - Category and tag indexes and feeds depend on post metadata and configuration
158
+ #
159
+ def inject_pages(lang=nil)
160
+ config = self.config(lang)
161
+
162
+ # Only clone these pages for additional languages
163
+ #
164
+ if Octopress.multilingual? && Octopress.site.config['lang'] != lang
165
+ add_indexes(config, lang, post_index)
166
+ add_indexes(config, lang, post_archive)
167
+ end
168
+
169
+ add_feeds(config, lang, main_feed)
170
+
171
+ if defined? Octopress::Linkblog
172
+ add_feeds(config, lang, links_feed)
173
+ add_feeds(config, lang, articles_feed)
174
+ end
175
+
176
+ add_meta_indexes(config, lang, 'category', 'categories')
177
+ add_meta_indexes(config, lang, 'tag', 'tags')
178
+ end
179
+
180
+ def add_indexes(config, lang, page)
181
+ if new_page = clone_page(page, lang)
182
+ if Bootstrap.add_page(new_page)
183
+ @pages << new_page
184
+ end
185
+ end
186
+ end
187
+
188
+ def add_feeds(config, lang, feed_template)
189
+ if feed_template
190
+ type = feed_type(feed_template)
191
+ if page = feed_template.new_page({
192
+ 'lang' => lang,
193
+ 'feed_type' => type,
194
+ 'permalink' => lang_permalink(lang, config['permalinks']["#{type}_feed"]),
195
+ 'plugin' => self
196
+ })
197
+
198
+ page.data['title'] = page_title(page, config)
199
+
200
+ if Bootstrap.add_page(page, "feeds")
201
+ Octopress.site.pages << page
202
+ else
203
+ feed_template.pages.delete(page)
204
+ end
205
+ end
206
+ end
207
+ end
208
+
209
+ # Generates tag or category index or feed pages for each category and language
210
+ # Unless configuration lists specific categories
211
+ #
212
+ def add_meta_indexes(config, lang, type, types)
213
+
214
+ # Get page/feed template for category or tag
215
+ page_template = self.send("#{type}_index")
216
+ feed_template = self.send("#{type}_feed")
217
+
218
+ # Don't continue if this plugin doesn't have templates for this
219
+ return unless page_template || feed_template
220
+
221
+ collection = if lang
222
+ Octopress::Multilingual.send("#{types}_by_language")[lang].keys
223
+ else
224
+ Octopress.site.send("#{types}").keys
225
+ end
226
+
227
+ # User configured categories or tags
228
+ configured = Array(config[types]).map(&:downcase)
229
+
230
+ # If configuration specifices tags or categories, only generate indexes for those
231
+ if !configured.empty?
232
+ collection.delete_if { |i| !configured.include?(i) }
233
+ end
234
+
235
+ collection.each do |item|
236
+ item = item.downcase
237
+
238
+ # Only add pages if plugin has a feed template for this item
239
+ # and it hasn't been disabled in the configuration
240
+ #
241
+ if page_template && config["#{type}_indexes"] != false
242
+ permalink = lang_permalink(lang, config['permalinks']["#{type}_index"]).sub(":#{type}", item)
243
+
244
+ page = page_template.new_page({
245
+ 'lang' => lang,
246
+ "#{type}" => item,
247
+ 'permalink' => permalink,
248
+ 'plugin' => self
249
+ })
250
+
251
+ page.data['title'] = page_title(page, config)
252
+ if Bootstrap.add_page(page, type)
253
+ Octopress.site.pages << page
254
+ else
255
+ page_template.pages.delete(page)
256
+ end
257
+ end
258
+
259
+ # Only add feeds if plugin has a feed template for this item
260
+ # and it hasn't been disabled in the configuration
261
+ #
262
+ if feed_template && config["#{type}_feeds"] != false
263
+ permalink = lang_permalink(lang, config['permalinks']["#{type}_feed"]).sub(":#{type}", item)
264
+
265
+ page = feed_template.new_page({
266
+ 'lang' => lang,
267
+ "#{type}" => item,
268
+ 'feed_type' => type,
269
+ 'permalink' => permalink,
270
+ 'plugin' => self
271
+ })
272
+
273
+ page.data['title'] = page_title(page, config)
274
+ if Bootstrap.add_page(page, 'feeds')
275
+ Octopress.site.pages << page
276
+ else
277
+ feed_template.delete(page)
278
+ end
279
+ end
280
+ end
281
+ end
282
+
283
+ # Creates a copy of an Ink Page asset
284
+ # configuring lang and permalink accordingly
285
+ #
286
+ def clone_page(page, lang)
287
+ return if page.nil?
288
+ new_page = page.clone({
289
+ 'lang' => lang,
290
+ 'permalink' => page_permalink(page, lang)
291
+ })
292
+
293
+ new_page.page.data['title'] = page_title(new_page.page, config(lang))
294
+ new_page.permalink_name = nil
295
+ new_page
296
+ end
297
+
298
+ # Ensure cloned pages have language in their permalinks
299
+ # Since pages are only cloned for multilingual sites
300
+ #
301
+ def page_permalink(page, lang)
302
+ permalink = config(lang)['permalinks'][page.permalink_name]
303
+
304
+ if permalink.include?(":lang")
305
+ permalink.sub(":lang", lang)
306
+ else
307
+ File.join("/#{lang}", permalink)
308
+ end
309
+ end
310
+
311
+ # Ensure language is set in permalink if language is defined
312
+ #
313
+ def lang_permalink(lang, permalink)
314
+ if lang
315
+ permalink.sub(":lang", lang)
316
+ else
317
+ permalink.sub("/:lang/", '/')
318
+ end
319
+ end
320
+
321
+
322
+ # Discern feed type based on filename
323
+ #
324
+ def feed_type(page)
325
+ if page.path.include? 'articles'
326
+ 'articles'
327
+ elsif page.path.include? 'links'
328
+ 'links'
329
+ elsif page.path.include? 'category'
330
+ 'category'
331
+ elsif page.path.include? 'tag'
332
+ 'tag'
333
+ else
334
+ 'main'
335
+ end
336
+ end
337
+
338
+ def page_type(page)
339
+ if page.path.include? 'feed'
340
+ "#{feed_type(page)}_feed"
341
+ elsif page.path.include? 'post_index'
342
+ "post_index"
343
+ elsif page.path.include? 'post_archive'
344
+ "post_archive"
345
+ elsif page.path.include? 'category_index'
346
+ "category_index"
347
+ elsif page.path.include? 'tag_index'
348
+ "tag_index"
349
+ end
350
+ end
351
+
352
+ def generic_title(type, config, lang=nil)
353
+ title = config['titles'][type]
354
+ title = title.sub(':site_name', Octopress.site.config['name'] || '')
355
+ if lang && Octopress.multilingual?
356
+ title = title.sub(':lang_name', Octopress::Multilingual.language_name(lang))
357
+ end
358
+ title
359
+ end
360
+
361
+ def page_title(page, config)
362
+ type = page_type(page)
363
+ title = generic_title(type, config, page.lang)
364
+
365
+ if type.match(/(category|tag)/)
366
+ key = type.sub(/_index|_feed/, '')
367
+ label = tag_or_category_label(page, key, config)
368
+ title = title.sub(":#{key}", label)
369
+ end
370
+
371
+ title
372
+ end
373
+
374
+ def tag_or_category_label(page, type, config)
375
+ label = page.data[type].capitalize
376
+
377
+ if labels = config["#{type}_labels"]
378
+ label = labels[type] || label
379
+ end
380
+
381
+ label
382
+ end
383
+
384
+ def site_name
385
+ Octopress.site.config['name'] ? '- :site_name' : ''
386
+ end
387
+
388
+
389
+ # Default configuration settings
390
+ # Plugin authors can use or override these settings
391
+ #
392
+ def post_index_config
393
+ <<-CONFIG
394
+ titles:
395
+ post_index: Posts #{site_name}
396
+
397
+ permalinks:
398
+ post_index: /
399
+ CONFIG
400
+ end
401
+
402
+ def post_archive_config
403
+ <<-CONFIG
404
+ titles:
405
+ post_archive: Archive #{site_name}
406
+
407
+ permalinks:
408
+ post_archive: /archive/
409
+ CONFIG
410
+ end
411
+
412
+ def category_index_config
413
+ <<-CONFIG
414
+ titles:
415
+ category_index: Posts in :category #{site_name}
416
+
417
+ permalinks:
418
+ category_index: #{"/:lang" if Octopress.multilingual?}/categories/:category/
419
+ CONFIG
420
+ end
421
+
422
+ def tag_index_config
423
+ <<-CONFIG
424
+ titles:
425
+ tag_index: Posts tagged with :tag #{site_name}
426
+
427
+ permalinks:
428
+ tag_index: #{"/:lang" if Octopress.multilingual?}/tags/:tag/
429
+ CONFIG
430
+ end
431
+
432
+ def main_feed_config
433
+ <<-CONFIG
434
+ titles:
435
+ main_feed: Posts #{site_name} #{"(:lang_name)" if Octopress.multilingual?}
436
+
437
+ permalinks:
438
+ main_feed: #{"/:lang" if Octopress.multilingual?}/feed/
439
+ CONFIG
440
+ end
441
+
442
+ def links_feed_config
443
+ <<-CONFIG
444
+ titles:
445
+ links_feed: Links #{site_name} #{"(:lang_name)" if Octopress.multilingual?}
446
+
447
+ permalinks:
448
+ links_feed: #{"/:lang" if Octopress.multilingual?}/feed/links/
449
+ CONFIG
450
+ end
451
+
452
+ def articles_feed_config
453
+ <<-CONFIG
454
+ titles:
455
+ articles_feed: Articles #{site_name} #{"(:lang_name)" if Octopress.multilingual?}
456
+
457
+ permalinks:
458
+ articles_feed: #{"/:lang" if Octopress.multilingual?}/feed/articles/
459
+ CONFIG
460
+ end
461
+
462
+ def category_feed_config
463
+ <<-CONFIG
464
+ titles:
465
+ category_feed: Posts in :category #{site_name} #{"(:lang_name)" if Octopress.multilingual?}
466
+
467
+ permalinks:
468
+ category_feed: #{"/:lang" if Octopress.multilingual?}/feed/categories/:category/
469
+ CONFIG
470
+ end
471
+
472
+ def tag_feed_config
473
+ <<-CONFIG
474
+ titles:
475
+ tag_feed: Posts tagged with :tag #{site_name} #{"(:lang_name)" if Octopress.multilingual?}
476
+
477
+ permalinks:
478
+ tag_feed: #{"/:lang" if Octopress.multilingual?}/feed/tags/:tag/
479
+ CONFIG
480
+ end
481
+
482
+ def category_config_defaults
483
+ <<-CONFIG
484
+ #{"category_indexes: false" if category_index }
485
+ #{"category_feeds: false" if category_feed }
486
+ categories: []
487
+ CONFIG
488
+ end
489
+
490
+ def tag_config_defaults
491
+ <<-CONFIG
492
+ #{"tag_indexes: false" if tag_index }
493
+ #{"tag_feeds: false" if tag_feed }
494
+ tags: []
495
+ CONFIG
496
+ end
497
+
498
+ def feed_config_defaults
499
+ <<-CONFIG
500
+ feed_count: 20 # Number of items in feeds
501
+ feed_excerpts: false # Use post excerpts in feeds
502
+ #{"posts_link_out: true" if links_feed }
503
+ CONFIG
504
+ end
505
+ end
506
+ end
507
+ end
@@ -47,6 +47,7 @@ module Octopress
47
47
  @registered = false
48
48
  @css_tags = []
49
49
  @js_tags = []
50
+ Bootstrap.reset
50
51
  end
51
52
 
52
53
  def register
@@ -3,6 +3,9 @@ module Octopress
3
3
  module Tags
4
4
  autoload :JavascriptTag, 'octopress-ink/tags/javascript'
5
5
  autoload :StylesheetTag, 'octopress-ink/tags/stylesheet'
6
+ autoload :CategoryTag, 'octopress-ink/tags/category_tag'
7
+ autoload :FeedsTag, 'octopress-ink/tags/feeds_tag'
8
+ autoload :FeedUpdatedTag, 'octopress-ink/tags/feed_updated_tag'
6
9
  end
7
10
  end
8
11
  end
@@ -0,0 +1,64 @@
1
+ module Octopress
2
+ module Ink
3
+ module Tags
4
+ class CategoryTag < Liquid::Tag
5
+ def initialize(tag, input, tokens)
6
+ super
7
+ @tag = tag
8
+ if !input.nil?
9
+ @input = input.strip
10
+ end
11
+ end
12
+
13
+ def render(context)
14
+ @context = context
15
+
16
+
17
+ # If no input is passed, render in context of current page
18
+ # This allows the tag to be used without input on post templates
19
+ # But in a page loop it should be told passed the post item
20
+ #
21
+
22
+ page = context[@input] || context['page']
23
+ items = page[item_name_plural]
24
+
25
+ return '' if items.nil? || items.empty?
26
+
27
+ items = items.sort.map do |item|
28
+ link = item_link(page, item)
29
+
30
+ if item_list?
31
+ link = "<li class='#{item_type}-list-item'>#{link}</li>"
32
+ end
33
+
34
+ link
35
+ end
36
+
37
+ if item_list?
38
+ "<ul class='#{item_name}-list'>#{items.join}</ul>"
39
+ else
40
+ "<span class='#{item_name}-links'>#{items.join(', ')}</span>"
41
+ end
42
+ end
43
+
44
+ def item_list?
45
+ @tag.end_with? '_list'
46
+ end
47
+
48
+ def item_name
49
+ @tag.match('tag') ? 'tag' : 'category'
50
+ end
51
+
52
+ def item_name_plural
53
+ @tag.match('tag') ? 'tags' : 'categories'
54
+ end
55
+
56
+ def item_link(page, item)
57
+ dir = Bootstrap.send(item_name, item, page['lang'])
58
+ path = File.join(@context['site']['baseurl'], dir)
59
+ "<a class='#{item_name}-link' href='#{path}'>#{item.capitalize}</a>"
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,26 @@
1
+ module Octopress
2
+ module Ink
3
+ module Tags
4
+ class FeedUpdatedTag < Liquid::Tag
5
+ def render(context)
6
+ feed = context['page.feed_type']
7
+ site = context['site']
8
+
9
+ if feed == 'category'
10
+ posts = site['categories'][context['page.category']]
11
+ else
12
+ posts = site[feed] || site['posts']
13
+ end
14
+
15
+ if posts && !posts.empty?
16
+ post = posts.sort_by do |p|
17
+ p.data['date_updated'] || p.date
18
+ end.last
19
+
20
+ post.data['date_updated_xml'] || post.data['date_xml']
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,19 @@
1
+ module Octopress
2
+ module Ink
3
+ module Tags
4
+ class FeedsTag < Liquid::Tag
5
+ def render(context)
6
+ tags = []
7
+ Bootstrap.feeds.each do |url, title|
8
+ tags << tag(url, title)
9
+ end
10
+ tags.join("\n")
11
+ end
12
+
13
+ def tag(url, title)
14
+ "<link href='#{url.sub('index.xml', '')}' title='#{title}' rel='alternate' type='application/atom+xml'>"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -16,6 +16,7 @@ module Octopress
16
16
  .gsub(/,$/,'') # remove commas from end of lines
17
17
  .gsub(/{\n/,"\n") # remove keys with empty hashes
18
18
  .gsub(/^\s+}\n/,'') # remove keys with empty hashes
19
+ .gsub(/\[\s+\]/,'[]') # remove whitespace in empty arrays
19
20
  end
20
21
  end
21
22
  end
@@ -1,5 +1,5 @@
1
1
  module Octopress
2
2
  module Ink
3
- VERSION = "1.0.0.rc.48"
3
+ VERSION = "1.0.0.rc.49"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: octopress-ink
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc.48
4
+ version: 1.0.0.rc.49
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Mathis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-20 00:00:00.000000000 Z
11
+ date: 2015-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: octopress-date-format
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: octopress
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +150,20 @@ dependencies:
136
150
  - - ">="
137
151
  - !ruby/object:Gem::Version
138
152
  version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: octopress-linkblog
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
139
167
  - !ruby/object:Gem::Dependency
140
168
  name: bundler
141
169
  requirement: !ruby/object:Gem::Requirement
@@ -151,7 +179,7 @@ dependencies:
151
179
  - !ruby/object:Gem::Version
152
180
  version: '1.7'
153
181
  - !ruby/object:Gem::Dependency
154
- name: pry-byebug
182
+ name: octopress-debugger
155
183
  requirement: !ruby/object:Gem::Requirement
156
184
  requirements:
157
185
  - - ">="
@@ -207,11 +235,14 @@ files:
207
235
  - lib/octopress-ink/jekyll/page.rb
208
236
  - lib/octopress-ink/jekyll/static_file.rb
209
237
  - lib/octopress-ink/jekyll/static_file_content.rb
210
- - lib/octopress-ink/jekyll/template_page.rb
211
238
  - lib/octopress-ink/plugin.rb
239
+ - lib/octopress-ink/plugin/bootstrap.rb
212
240
  - lib/octopress-ink/plugin_asset_pipeline.rb
213
241
  - lib/octopress-ink/plugins.rb
214
242
  - lib/octopress-ink/tags.rb
243
+ - lib/octopress-ink/tags/category_tag.rb
244
+ - lib/octopress-ink/tags/feed_updated_tag.rb
245
+ - lib/octopress-ink/tags/feeds_tag.rb
215
246
  - lib/octopress-ink/tags/javascript.rb
216
247
  - lib/octopress-ink/tags/set_lang.rb
217
248
  - lib/octopress-ink/tags/stylesheet.rb
@@ -1,14 +0,0 @@
1
- module Octopress
2
- module Ink
3
- class TemplatePage < Jekyll::Page
4
- attr_accessor :dir, :name
5
- include Ink::Convertible
6
-
7
- def relative_asset_path
8
- site_source = Pathname.new Octopress.site.source
9
- page_source = Pathname.new @base
10
- page_source.relative_path_from(site_source).to_s
11
- end
12
- end
13
- end
14
- end