ruhoh 0.0.3 → 0.0.6
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/README.md +41 -0
- data/bin/ruhoh +6 -0
- data/lib/ruhoh/client/client.rb +26 -9
- data/lib/ruhoh/client/help.yml +4 -0
- data/lib/ruhoh/compiler.rb +7 -5
- data/lib/ruhoh/logger.rb +37 -0
- data/lib/ruhoh/page.rb +4 -4
- data/lib/ruhoh/parsers/pages.rb +9 -4
- data/lib/ruhoh/templaters/base.rb +12 -8
- data/lib/ruhoh/templaters/helpers.rb +59 -63
- data/lib/ruhoh/utils.rb +6 -1
- data/lib/ruhoh/version.rb +2 -1
- data/lib/ruhoh.rb +27 -18
- data/ruhoh.gemspec +1 -29
- data/spec/db_spec.rb +1 -1
- data/spec/page_spec.rb +1 -1
- data/spec/parsers/layouts_spec.rb +1 -1
- data/spec/parsers/pages_spec.rb +5 -5
- data/spec/parsers/posts_spec.rb +1 -1
- data/spec/parsers/routes_spec.rb +1 -1
- data/spec/parsers/site_spec.rb +1 -1
- data/system_partials/syntax/google_prettify +1 -1
- metadata +11 -39
- data/scaffolds/blog/_config.yml +0 -33
- data/scaffolds/blog/_drafts/.gitkeep +0 -0
- data/scaffolds/blog/_posts/.gitkeep +0 -0
- data/scaffolds/blog/_site.yml +0 -16
- data/scaffolds/blog/_templates/partials/categories_list +0 -3
- data/scaffolds/blog/_templates/partials/pages_list +0 -7
- data/scaffolds/blog/_templates/partials/posts_collate +0 -9
- data/scaffolds/blog/_templates/partials/posts_list +0 -1
- data/scaffolds/blog/_templates/partials/tags_list +0 -3
- data/scaffolds/blog/_templates/syntax/google_prettify/default.css +0 -52
- data/scaffolds/blog/_templates/syntax/google_prettify/desert.css +0 -34
- data/scaffolds/blog/_templates/syntax/google_prettify/sons-of-obsidian.css +0 -117
- data/scaffolds/blog/_templates/syntax/google_prettify/sunburst.css +0 -51
- data/scaffolds/blog/_templates/syntax/google_prettify/twitter-bootstrap.css +0 -30
- data/scaffolds/blog/_templates/themes/twitter/bootstrap/css/bootstrap.min.css +0 -689
- data/scaffolds/blog/_templates/themes/twitter/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/scaffolds/blog/_templates/themes/twitter/bootstrap/img/glyphicons-halflings.png +0 -0
- data/scaffolds/blog/_templates/themes/twitter/css/style.css +0 -68
- data/scaffolds/blog/_templates/themes/twitter/layouts/default.html +0 -64
- data/scaffolds/blog/_templates/themes/twitter/layouts/page.html +0 -13
- data/scaffolds/blog/_templates/themes/twitter/layouts/post.html +0 -55
- data/scaffolds/blog/_templates/themes/twitter/manifest.yml +0 -11
- data/scaffolds/blog/about.md +0 -5
- data/scaffolds/blog/archive.html +0 -11
- data/scaffolds/blog/categories.html +0 -21
- data/scaffolds/blog/config.ru +0 -9
- data/scaffolds/blog/index.html +0 -13
- data/scaffolds/blog/pages.html +0 -14
- data/scaffolds/blog/tags.html +0 -21
data/README.md
CHANGED
@@ -7,3 +7,44 @@
|
|
7
7
|
|
8
8
|
$ gem install ruhoh
|
9
9
|
$ ruhoh help
|
10
|
+
|
11
|
+
|
12
|
+
# SIMPLIFY SIMPLIFY SIMPLIFY
|
13
|
+
|
14
|
+
# Fronts
|
15
|
+
|
16
|
+
## ruhoh hosting
|
17
|
+
|
18
|
+
User Workflow:
|
19
|
+
|
20
|
+
- user auths with ruhoh.com
|
21
|
+
ruhoh expects a users blog to be in the GitHub repo: username.ruhoh.com
|
22
|
+
- user gives GitHub the ruhoh.com POST receive hook for his username.ruhoh.com repo
|
23
|
+
|
24
|
+
Implementation:
|
25
|
+
|
26
|
+
Sinatra app
|
27
|
+
handle POST requests from GitHub post receive hook.
|
28
|
+
oAuth via GitHub provider.
|
29
|
+
user accounts via GitHub oAuth.
|
30
|
+
wildcard domain name mapping: *.ruhoh.com
|
31
|
+
|
32
|
+
git clone/fetch repositories and compile the blog for hosting.
|
33
|
+
|
34
|
+
|
35
|
+
x] create server on linode
|
36
|
+
x] host sinatra app at app.ruhoh.com
|
37
|
+
send post receive hook to app.ruhoh.com
|
38
|
+
|
39
|
+
hook should trigger git clone if repo does not exist.
|
40
|
+
hook should trigger git pull/fetch if repo does exist
|
41
|
+
repo should compile after repo update
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
## Sbvtle
|
46
|
+
|
47
|
+
Adopt the admin UI at /\_drafts
|
48
|
+
|
49
|
+
|
50
|
+
|
data/bin/ruhoh
CHANGED
@@ -20,6 +20,12 @@ opt_parser = OptionParser.new do |opts|
|
|
20
20
|
options.verbose = v
|
21
21
|
end
|
22
22
|
|
23
|
+
opts.on("--version", "Display current gem and ruhoh specification versions.") do
|
24
|
+
puts "ruhoh " + Ruhoh::VERSION
|
25
|
+
puts "RuhohSpec " + Ruhoh::RuhohSpec
|
26
|
+
exit 0
|
27
|
+
end
|
28
|
+
|
23
29
|
end
|
24
30
|
opt_parser.parse!
|
25
31
|
|
data/lib/ruhoh/client/client.rb
CHANGED
@@ -3,7 +3,8 @@ require 'ruhoh/compiler'
|
|
3
3
|
class Ruhoh
|
4
4
|
class Client
|
5
5
|
|
6
|
-
Paths = Struct.new(:
|
6
|
+
Paths = Struct.new(:page_template, :post_template, :layout_template, :theme_template)
|
7
|
+
BlogScaffold = 'git://github.com/ruhoh/blog.git'
|
7
8
|
|
8
9
|
def initialize(data)
|
9
10
|
self.setup_paths
|
@@ -29,7 +30,6 @@ class Ruhoh
|
|
29
30
|
|
30
31
|
def setup_paths
|
31
32
|
@paths = Paths.new
|
32
|
-
@paths.blog_template = File.join(Ruhoh::Root, "scaffolds", "blog")
|
33
33
|
@paths.page_template = File.join(Ruhoh::Root, "scaffolds", "page.html")
|
34
34
|
@paths.post_template = File.join(Ruhoh::Root, "scaffolds", "post.html")
|
35
35
|
@paths.layout_template = File.join(Ruhoh::Root, "scaffolds", "layout.html")
|
@@ -60,7 +60,7 @@ class Ruhoh
|
|
60
60
|
def draft
|
61
61
|
filename = File.join(Ruhoh.paths.drafts, "#{Time.now.to_i}.#{@options.ext}")
|
62
62
|
if File.exist?(filename)
|
63
|
-
sleep 1 ; self.
|
63
|
+
sleep 1 ; self.draft(args) ; exit
|
64
64
|
end
|
65
65
|
|
66
66
|
FileUtils.mkdir_p File.dirname(filename)
|
@@ -73,6 +73,7 @@ class Ruhoh
|
|
73
73
|
Ruhoh::Friend.say {
|
74
74
|
green "New draft:"
|
75
75
|
green Ruhoh.relative_path(filename)
|
76
|
+
green 'View drafts at the URL: /_drafts'
|
76
77
|
}
|
77
78
|
end
|
78
79
|
|
@@ -129,7 +130,7 @@ class Ruhoh
|
|
129
130
|
exit
|
130
131
|
} if (name.nil? || name.gsub(/\s/, '').empty?)
|
131
132
|
|
132
|
-
filename = File.join(Ruhoh.paths.
|
133
|
+
filename = File.join(Ruhoh.paths.pages, name.gsub(/\s/, '-'))
|
133
134
|
filename = File.join(filename, "index.#{@options.ext}") if File.extname(filename) == ""
|
134
135
|
if File.exist?(filename)
|
135
136
|
abort("Create new page: aborted!") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n'
|
@@ -169,13 +170,20 @@ class Ruhoh
|
|
169
170
|
plain " Specify another directory or `rm -rf` this directory first."
|
170
171
|
exit
|
171
172
|
} if File.exist?(target_directory)
|
172
|
-
|
173
|
-
FileUtils.mkdir target_directory
|
174
|
-
FileUtils.cp_r "#{@paths.blog_template}/.", target_directory
|
175
173
|
|
176
174
|
Ruhoh::Friend.say {
|
177
|
-
|
178
|
-
|
175
|
+
plain "Trying this command:"
|
176
|
+
cyan " git clone #{BlogScaffold} #{target_directory}"
|
177
|
+
|
178
|
+
if system('git', 'clone', BlogScaffold, target_directory)
|
179
|
+
green "Success! Now do..."
|
180
|
+
cyan " cd #{target_directory}"
|
181
|
+
cyan " rackup -p9292"
|
182
|
+
cyan " http://localhost:9292"
|
183
|
+
else
|
184
|
+
red "Could not git clone blog scaffold. Please try it manually:"
|
185
|
+
cyan " git clone git://github.com/ruhoh/blog.git #{target_directory}"
|
186
|
+
end
|
179
187
|
}
|
180
188
|
end
|
181
189
|
|
@@ -245,6 +253,15 @@ class Ruhoh
|
|
245
253
|
self.list(:pages)
|
246
254
|
end
|
247
255
|
|
256
|
+
# Return the payload hash for inspection/study.
|
257
|
+
def payload
|
258
|
+
require 'pp'
|
259
|
+
Ruhoh::DB.update!
|
260
|
+
Ruhoh::Friend.say {
|
261
|
+
plain Ruhoh::Templaters::Base.build_payload.pretty_inspect
|
262
|
+
}
|
263
|
+
end
|
264
|
+
|
248
265
|
# Internal: Outputs a list of the given data-type to the terminal.
|
249
266
|
def list(type)
|
250
267
|
Ruhoh::DB.update(type)
|
data/lib/ruhoh/client/help.yml
CHANGED
@@ -42,6 +42,10 @@ commands:
|
|
42
42
|
"command" : "pages"
|
43
43
|
"desc" : |
|
44
44
|
List all pages.
|
45
|
+
-
|
46
|
+
"command" : "payload"
|
47
|
+
"desc" : |
|
48
|
+
List the full payload hash as given to the templater. Note page is blank for example purposes.
|
45
49
|
-
|
46
50
|
"command" : "layout <name>"
|
47
51
|
"desc" : |
|
data/lib/ruhoh/compiler.rb
CHANGED
@@ -8,18 +8,18 @@ class Ruhoh
|
|
8
8
|
@page = Ruhoh::Page.new
|
9
9
|
end
|
10
10
|
|
11
|
+
# TODO: seems rather dangerous to delete the incoming target directory?
|
11
12
|
def compile
|
12
13
|
FileUtils.rm_r @target if File.exist?(@target)
|
13
|
-
FileUtils.
|
14
|
+
FileUtils.mkdir_p @target
|
14
15
|
self.theme
|
15
16
|
self.pages
|
16
17
|
self.media
|
17
18
|
self.syntax
|
19
|
+
true
|
18
20
|
end
|
19
21
|
|
20
22
|
def pages
|
21
|
-
processed = []
|
22
|
-
|
23
23
|
FileUtils.cd(@target) {
|
24
24
|
Ruhoh::DB.posts['dictionary'].merge(Ruhoh::DB.pages).each_value do |p|
|
25
25
|
@page.change(p['id'])
|
@@ -27,7 +27,6 @@ class Ruhoh
|
|
27
27
|
FileUtils.mkdir_p File.dirname(@page.compiled_path)
|
28
28
|
File.open(@page.compiled_path, 'w') { |p| p.puts @page.render }
|
29
29
|
|
30
|
-
processed << p
|
31
30
|
Ruhoh::Friend.say { green "processed: #{p['id']}" }
|
32
31
|
end
|
33
32
|
}
|
@@ -35,16 +34,19 @@ class Ruhoh
|
|
35
34
|
end
|
36
35
|
|
37
36
|
def theme
|
37
|
+
return unless FileTest.directory? Ruhoh.paths.theme
|
38
38
|
FileUtils.mkdir_p File.join(@target, Ruhoh.config.theme_path)
|
39
39
|
FileUtils.cp_r Ruhoh.paths.theme, File.join(@target, Ruhoh.folders.templates, Ruhoh.folders.themes)
|
40
40
|
end
|
41
41
|
|
42
42
|
def media
|
43
|
+
return unless FileTest.directory? Ruhoh.paths.media
|
43
44
|
FileUtils.mkdir_p File.join(@target, Ruhoh.folders.media)
|
44
|
-
FileUtils.cp_r Ruhoh.paths.media, @target
|
45
|
+
FileUtils.cp_r Ruhoh.paths.media, @target
|
45
46
|
end
|
46
47
|
|
47
48
|
def syntax
|
49
|
+
return unless FileTest.directory? Ruhoh.paths.syntax
|
48
50
|
syntax_path = File.join(@target, Ruhoh.folders.templates, Ruhoh.folders.syntax)
|
49
51
|
FileUtils.mkdir_p syntax_path
|
50
52
|
FileUtils.cp_r "#{Ruhoh.paths.syntax}/.", syntax_path
|
data/lib/ruhoh/logger.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
class Ruhoh
|
2
|
+
class Logger
|
3
|
+
|
4
|
+
attr_reader :buffer
|
5
|
+
attr_accessor :log_file
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@buffer = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def error(string=nil)
|
12
|
+
message = ""
|
13
|
+
message << string if string
|
14
|
+
message << "\n" unless message[-1] == ?\n
|
15
|
+
@buffer << message
|
16
|
+
|
17
|
+
self.on_error
|
18
|
+
end
|
19
|
+
|
20
|
+
def on_error
|
21
|
+
msg = @buffer[0]
|
22
|
+
Ruhoh::Friend.say { red msg }
|
23
|
+
self.to_file
|
24
|
+
exit -1
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_file
|
28
|
+
return unless self.log_file && @buffer.size > 0
|
29
|
+
File.open(self.log_file, "a") { |f|
|
30
|
+
f.puts '---'
|
31
|
+
f.puts Time.now.utc
|
32
|
+
f.puts @buffer.slice!(0..-1).join
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
end #Logger
|
37
|
+
end #Ruhoh
|
data/lib/ruhoh/page.rb
CHANGED
@@ -12,12 +12,13 @@ class Ruhoh
|
|
12
12
|
# Public: Change this page using an id.
|
13
13
|
def change(id)
|
14
14
|
@data = nil
|
15
|
-
|
15
|
+
@path = id
|
16
16
|
@data = if id =~ Regexp.new("^#{Ruhoh.folders.posts}")
|
17
17
|
Ruhoh::DB.posts['dictionary'][id]
|
18
18
|
elsif id =~ Regexp.new("^#{Ruhoh.folders.drafts}")
|
19
19
|
Ruhoh::DB.drafts[id]
|
20
20
|
else
|
21
|
+
@path = "#{Ruhoh.folders.pages}/#{id}"
|
21
22
|
Ruhoh::DB.pages[id]
|
22
23
|
end
|
23
24
|
|
@@ -32,7 +33,6 @@ class Ruhoh
|
|
32
33
|
else
|
33
34
|
Ruhoh::DB.routes[url]
|
34
35
|
end
|
35
|
-
|
36
36
|
raise "Page id not found for url: #{url}" unless id
|
37
37
|
self.change(id)
|
38
38
|
end
|
@@ -62,8 +62,8 @@ class Ruhoh
|
|
62
62
|
# Converters (markdown) always choke on the templating language.
|
63
63
|
def process_content
|
64
64
|
raise "ID is null: Id must be set via page.change(id) or page.change_with_url(url)" if @id.nil?
|
65
|
-
data = Ruhoh::Utils.parse_file(Ruhoh.paths.site_source, @
|
66
|
-
raise "Invalid Frontmatter in page: #{@
|
65
|
+
data = Ruhoh::Utils.parse_file(Ruhoh.paths.site_source, @path)
|
66
|
+
raise "Invalid Frontmatter in page: #{@path}" if data.empty?
|
67
67
|
|
68
68
|
@content = @templater.parse(data['content'], self)
|
69
69
|
@content = @converter.convert(self)
|
data/lib/ruhoh/parsers/pages.rb
CHANGED
@@ -14,17 +14,18 @@ class Ruhoh
|
|
14
14
|
dictionary = {}
|
15
15
|
|
16
16
|
pages.each do |filename|
|
17
|
+
id = self.make_id(filename)
|
17
18
|
parsed_page = Ruhoh::Utils.parse_file(filename)
|
18
19
|
if parsed_page.empty?
|
19
20
|
error = "Invalid Yaml Front Matter.\n Ensure this page has valid YAML, even if it's empty."
|
20
21
|
invalid << [filename, error] ; next
|
21
22
|
end
|
22
23
|
|
23
|
-
parsed_page['data']['id'] =
|
24
|
+
parsed_page['data']['id'] = id
|
24
25
|
parsed_page['data']['url'] = self.permalink(parsed_page['data'])
|
25
26
|
parsed_page['data']['title'] = parsed_page['data']['title'] || self.titleize(filename)
|
26
27
|
|
27
|
-
dictionary[
|
28
|
+
dictionary[id] = parsed_page['data']
|
28
29
|
end
|
29
30
|
|
30
31
|
report = "#{pages.count - invalid.count }/#{pages.count} pages processed."
|
@@ -45,7 +46,7 @@ class Ruhoh
|
|
45
46
|
|
46
47
|
def self.files
|
47
48
|
FileUtils.cd(Ruhoh.paths.site_source) {
|
48
|
-
return Dir["
|
49
|
+
return Dir["#{Ruhoh.folders.pages}/**/*.*"].select { |filename|
|
49
50
|
next unless self.is_valid_page?(filename)
|
50
51
|
true
|
51
52
|
}
|
@@ -54,12 +55,16 @@ class Ruhoh
|
|
54
55
|
|
55
56
|
def self.is_valid_page?(filepath)
|
56
57
|
return false if FileTest.directory?(filepath)
|
57
|
-
return false if ['
|
58
|
+
return false if ['.'].include? filepath[0]
|
58
59
|
return false if Ruhoh.filters.pages['names'].include? filepath
|
59
60
|
Ruhoh.filters.pages['regexes'].each {|regex| return false if filepath =~ regex }
|
60
61
|
true
|
61
62
|
end
|
62
63
|
|
64
|
+
def self.make_id(filename)
|
65
|
+
filename.gsub(Regexp.new("^#{Ruhoh.folders.pages}/"), '')
|
66
|
+
end
|
67
|
+
|
63
68
|
def self.titleize(filename)
|
64
69
|
name = File.basename( filename, File.extname(filename) )
|
65
70
|
name = filename.split('/')[-2] if name == 'index' && !filename.index('/').nil?
|
@@ -4,15 +4,19 @@ class Ruhoh
|
|
4
4
|
|
5
5
|
module Base
|
6
6
|
|
7
|
-
def self.build_payload(page)
|
7
|
+
def self.build_payload(page=nil)
|
8
8
|
{
|
9
|
-
"
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
"
|
14
|
-
"
|
15
|
-
"
|
9
|
+
"db" => {
|
10
|
+
"pages" => Ruhoh::DB.pages,
|
11
|
+
"posts" => Ruhoh::DB.posts,
|
12
|
+
},
|
13
|
+
"page" => (page ? page.attributes : {}),
|
14
|
+
"site" => Ruhoh::DB.site,
|
15
|
+
"paths" => {
|
16
|
+
"theme" => Ruhoh.config.theme_path,
|
17
|
+
"syntax" => Ruhoh.config.syntax_path,
|
18
|
+
"media" => Ruhoh.config.media_path
|
19
|
+
}
|
16
20
|
}
|
17
21
|
end
|
18
22
|
|
@@ -1,15 +1,35 @@
|
|
1
1
|
require 'pp'
|
2
2
|
|
3
3
|
class Ruhoh
|
4
|
-
|
5
4
|
module Templaters
|
6
|
-
|
7
5
|
module Helpers
|
8
|
-
|
6
|
+
|
9
7
|
def partial(name)
|
10
8
|
Ruhoh::DB.partials[name.to_s]
|
11
9
|
end
|
12
|
-
|
10
|
+
|
11
|
+
def pages
|
12
|
+
pages = []
|
13
|
+
self.context['db']['pages'].each_value {|page| pages << page }
|
14
|
+
self.mark_active_page(pages)
|
15
|
+
end
|
16
|
+
|
17
|
+
def posts
|
18
|
+
self.to_posts(self.context['db']['posts']['chronological'])
|
19
|
+
end
|
20
|
+
|
21
|
+
def categories
|
22
|
+
cats = []
|
23
|
+
self.context['db']['posts']['categories'].each_value { |cat| cats << cat }
|
24
|
+
cats
|
25
|
+
end
|
26
|
+
|
27
|
+
def tags
|
28
|
+
tags = []
|
29
|
+
self.context['db']['posts']['categories'].each_value { |tag| tags << tag }
|
30
|
+
tags
|
31
|
+
end
|
32
|
+
|
13
33
|
def raw_code(sub_context)
|
14
34
|
code = sub_context.gsub('{', '{').gsub('}', '}').gsub('<', '<').gsub('>', '>')
|
15
35
|
"<pre><code>#{code}</code></pre>"
|
@@ -25,84 +45,51 @@ class Ruhoh
|
|
25
45
|
"<pre>#{sub_context.class}\n#{sub_context.pretty_inspect}</pre>"
|
26
46
|
end
|
27
47
|
|
28
|
-
def to_tags(sub_context)
|
29
|
-
if sub_context.is_a?(Array)
|
30
|
-
sub_context.map { |id|
|
31
|
-
self.context['_posts']['tags'][id] if self.context['_posts']['tags'][id]
|
32
|
-
}
|
33
|
-
else
|
34
|
-
tags = []
|
35
|
-
self.context['_posts']['tags'].each_value { |tag|
|
36
|
-
tags << tag
|
37
|
-
}
|
38
|
-
tags
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
48
|
def to_posts(sub_context)
|
43
|
-
sub_context
|
44
|
-
|
45
|
-
|
46
|
-
self.context['_posts']['dictionary'][id] if self.context['_posts']['dictionary'][id]
|
47
|
-
}
|
49
|
+
Array(sub_context).map { |id|
|
50
|
+
self.context['db']['posts']['dictionary'][id]
|
51
|
+
}.compact
|
48
52
|
end
|
49
53
|
|
50
54
|
def to_pages(sub_context)
|
51
|
-
pages =
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
pages << self.context[:pages][id]
|
56
|
-
end
|
57
|
-
end
|
58
|
-
else
|
59
|
-
self.context[:pages].each_value {|page| pages << page }
|
60
|
-
end
|
61
|
-
|
62
|
-
pages.each_with_index do |page, i|
|
63
|
-
next unless page['id'] == self.context[:page]['id']
|
64
|
-
active_page = page.dup
|
65
|
-
active_page['is_active_page'] = true
|
66
|
-
pages[i] = active_page
|
67
|
-
end
|
68
|
-
|
69
|
-
pages
|
55
|
+
pages = Array(sub_context).map { |id|
|
56
|
+
self.context['db']['pages'][id]
|
57
|
+
}.compact
|
58
|
+
self.mark_active_page(pages)
|
70
59
|
end
|
71
|
-
|
60
|
+
|
72
61
|
def to_categories(sub_context)
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
}
|
77
|
-
else
|
78
|
-
cats = []
|
79
|
-
self.context['_posts']['categories'].each_value { |cat|
|
80
|
-
cats << cat
|
81
|
-
}
|
82
|
-
cats
|
83
|
-
end
|
62
|
+
Array(sub_context).map { |id|
|
63
|
+
self.context['db']['posts']['categories'][id]
|
64
|
+
}.compact
|
84
65
|
end
|
85
|
-
|
66
|
+
|
67
|
+
def to_tags(sub_context)
|
68
|
+
Array(sub_context).map { |id|
|
69
|
+
self.context['db']['posts']['tags'][id]
|
70
|
+
}.compact
|
71
|
+
end
|
72
|
+
|
86
73
|
def next(sub_context)
|
87
74
|
return unless sub_context.is_a?(String) || sub_context.is_a?(Hash)
|
88
75
|
id = sub_context.is_a?(Hash) ? sub_context['id'] : sub_context
|
89
76
|
return unless id
|
90
|
-
index = self.context['
|
77
|
+
index = self.context['db']['posts']['chronological'].index(id)
|
91
78
|
return unless index && (index-1 >= 0)
|
92
|
-
next_id = self.context['
|
79
|
+
next_id = self.context['db']['posts']['chronological'][index-1]
|
93
80
|
return unless next_id
|
94
|
-
self.to_posts(
|
81
|
+
self.to_posts(next_id)
|
95
82
|
end
|
96
83
|
|
97
84
|
def previous(sub_context)
|
98
85
|
return unless sub_context.is_a?(String) || sub_context.is_a?(Hash)
|
99
86
|
id = sub_context.is_a?(Hash) ? sub_context['id'] : sub_context
|
100
87
|
return unless id
|
101
|
-
index = self.context['
|
88
|
+
index = self.context['db']['posts']['chronological'].index(id)
|
102
89
|
return unless index && (index+1 >= 0)
|
103
|
-
prev_id = self.context['
|
90
|
+
prev_id = self.context['db']['posts']['chronological'][index+1]
|
104
91
|
return unless prev_id
|
105
|
-
self.to_posts(
|
92
|
+
self.to_posts(prev_id)
|
106
93
|
end
|
107
94
|
|
108
95
|
def analytics
|
@@ -152,8 +139,17 @@ class Ruhoh
|
|
152
139
|
self.render(code)
|
153
140
|
end
|
154
141
|
|
142
|
+
# Marks the active page if exists in the given pages Array
|
143
|
+
def mark_active_page(pages)
|
144
|
+
pages.each_with_index do |page, i|
|
145
|
+
next unless page['id'] == self.context[:page]['id']
|
146
|
+
active_page = page.dup
|
147
|
+
active_page['is_active_page'] = true
|
148
|
+
pages[i] = active_page
|
149
|
+
end
|
150
|
+
pages
|
151
|
+
end
|
152
|
+
|
155
153
|
end #Helpers
|
156
|
-
|
157
154
|
end #Templaters
|
158
|
-
|
159
155
|
end #Ruhoh
|
data/lib/ruhoh/utils.rb
CHANGED
@@ -12,8 +12,10 @@ class Ruhoh
|
|
12
12
|
file = File.open(filepath)
|
13
13
|
yaml = YAML.load(file) || {}
|
14
14
|
file.close
|
15
|
-
|
16
15
|
yaml
|
16
|
+
rescue Psych::SyntaxError => e
|
17
|
+
Ruhoh.log.error("ERROR in #{filepath}: #{e.message}")
|
18
|
+
nil
|
17
19
|
end
|
18
20
|
|
19
21
|
def self.parse_file(*args)
|
@@ -33,6 +35,9 @@ class Ruhoh
|
|
33
35
|
"data" => self.format_meta(data),
|
34
36
|
"content" => page.gsub(FMregex, '')
|
35
37
|
}
|
38
|
+
rescue Psych::SyntaxError => e
|
39
|
+
Ruhoh.log.error("ERROR in #{path}: #{e.message}")
|
40
|
+
nil
|
36
41
|
end
|
37
42
|
|
38
43
|
def self.format_meta(data)
|
data/lib/ruhoh/version.rb
CHANGED
data/lib/ruhoh.rb
CHANGED
@@ -6,6 +6,7 @@ require 'fileutils'
|
|
6
6
|
|
7
7
|
require 'mustache'
|
8
8
|
|
9
|
+
require 'ruhoh/logger'
|
9
10
|
require 'ruhoh/utils'
|
10
11
|
require 'ruhoh/friend'
|
11
12
|
require 'ruhoh/parsers/drafts'
|
@@ -26,17 +27,23 @@ require 'ruhoh/watch'
|
|
26
27
|
|
27
28
|
class Ruhoh
|
28
29
|
|
29
|
-
class << self
|
30
|
+
class << self
|
31
|
+
attr_accessor :log
|
32
|
+
attr_reader :folders, :files, :config, :paths, :filters
|
33
|
+
end
|
34
|
+
|
35
|
+
@log = Ruhoh::Logger.new
|
30
36
|
|
31
37
|
Root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
32
38
|
DefaultExclude = ['Gemfile', 'Gemfile.lock', 'config.ru', 'README.md']
|
33
|
-
Folders = Struct.new(:database, :posts, :drafts, :templates, :themes, :layouts, :partials, :media, :syntax, :compiled)
|
39
|
+
Folders = Struct.new(:database, :pages, :posts, :drafts, :templates, :themes, :layouts, :partials, :media, :syntax, :compiled)
|
34
40
|
Files = Struct.new(:site, :config)
|
35
41
|
Filters = Struct.new(:posts, :pages, :static)
|
36
42
|
Config = Struct.new(:permalink, :theme, :theme_path, :media_path, :syntax_path, :exclude)
|
37
43
|
Paths = Struct.new(
|
38
44
|
:site_source,
|
39
45
|
:database,
|
46
|
+
:pages,
|
40
47
|
:posts,
|
41
48
|
:drafts,
|
42
49
|
:theme,
|
@@ -49,20 +56,18 @@ class Ruhoh
|
|
49
56
|
)
|
50
57
|
|
51
58
|
|
52
|
-
# Public: Setup Ruhoh utilities relative to the current directory
|
53
|
-
#
|
54
|
-
|
55
|
-
|
59
|
+
# Public: Setup Ruhoh utilities relative to the current application directory.
|
60
|
+
# Returns boolean on success/failure
|
61
|
+
def self.setup(opts={})
|
62
|
+
@log.log_file = opts[:log_file] if opts[:log_file]
|
56
63
|
self.reset
|
64
|
+
@site_source = opts[:source] if opts[:source]
|
57
65
|
|
58
|
-
|
59
|
-
self.setup_config
|
60
|
-
self.setup_paths
|
61
|
-
self.setup_filters
|
66
|
+
!!(self.setup_config && self.setup_paths && self.setup_filters)
|
62
67
|
end
|
63
68
|
|
64
69
|
def self.reset
|
65
|
-
@folders = Folders.new('_database', '_posts', '_drafts', '_templates', 'themes', 'layouts', 'partials', "_media", "syntax", '_compiled')
|
70
|
+
@folders = Folders.new('_database', '_pages', '_posts', '_drafts', '_templates', 'themes', 'layouts', 'partials', "_media", "syntax", '_compiled')
|
66
71
|
@files = Files.new('_site.yml', '_config.yml')
|
67
72
|
@filters = Filters.new
|
68
73
|
@config = Config.new
|
@@ -72,17 +77,18 @@ class Ruhoh
|
|
72
77
|
|
73
78
|
def self.setup_config
|
74
79
|
site_config = Ruhoh::Utils.parse_file_as_yaml(@site_source, @files.config)
|
80
|
+
|
75
81
|
unless site_config
|
76
|
-
Ruhoh
|
77
|
-
|
78
|
-
red "Please ensure ./#{Ruhoh.files.config} exists and contains valid YAML"
|
79
|
-
}
|
80
|
-
exit
|
82
|
+
Ruhoh.log.error("Empty site_config.\nEnsure ./#{Ruhoh.files.config} exists and contains valid YAML")
|
83
|
+
return false
|
81
84
|
end
|
82
85
|
|
83
86
|
theme = site_config['theme'] ? site_config['theme'].to_s.gsub(/\s/, '') : ''
|
84
|
-
|
85
|
-
|
87
|
+
if theme.empty?
|
88
|
+
Ruhoh.log.error("Theme not specified in _config.yml")
|
89
|
+
return false
|
90
|
+
end
|
91
|
+
|
86
92
|
@config.theme = theme
|
87
93
|
@config.theme_path = File.join('/', @folders.templates, @folders.themes, @config.theme)
|
88
94
|
@config.media_path = File.join('/', @folders.media)
|
@@ -94,6 +100,7 @@ class Ruhoh
|
|
94
100
|
def self.setup_paths
|
95
101
|
@paths.site_source = @site_source
|
96
102
|
@paths.database = self.absolute_path(@folders.database)
|
103
|
+
@paths.pages = self.absolute_path(@folders.pages)
|
97
104
|
@paths.posts = self.absolute_path(@folders.posts)
|
98
105
|
@paths.drafts = self.absolute_path(@folders.drafts)
|
99
106
|
|
@@ -104,6 +111,7 @@ class Ruhoh
|
|
104
111
|
@paths.media = self.absolute_path(@folders.media)
|
105
112
|
@paths.syntax = self.absolute_path(@folders.templates, @folders.syntax)
|
106
113
|
@paths.compiled = self.absolute_path(@folders.compiled)
|
114
|
+
@paths
|
107
115
|
end
|
108
116
|
|
109
117
|
# filename filters
|
@@ -116,6 +124,7 @@ class Ruhoh
|
|
116
124
|
@filters.pages['names'] << node if node.is_a?(String)
|
117
125
|
@filters.pages['regexes'] << node if node.is_a?(Regexp)
|
118
126
|
}
|
127
|
+
@filters
|
119
128
|
end
|
120
129
|
|
121
130
|
def self.absolute_path(*args)
|