ruhoh 2.4 → 2.5
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/features/date_format.feature +41 -0
- data/features/step_defs.rb +25 -0
- data/history.json +21 -0
- data/lib/ruhoh.rb +4 -1
- data/lib/ruhoh/base/model.rb +11 -1
- data/lib/ruhoh/base/model_view.rb +1 -4
- data/lib/ruhoh/client.rb +47 -3
- data/lib/ruhoh/parse.rb +1 -1
- data/lib/ruhoh/programs/compile.rb +4 -2
- data/lib/ruhoh/publish/rsync.rb +36 -0
- data/lib/ruhoh/resources/pages/client.rb +2 -2
- data/lib/ruhoh/resources/pages/collection_view.rb +4 -4
- data/lib/ruhoh/resources/pages/previewer.rb +3 -11
- data/lib/ruhoh/resources/partials/model.rb +2 -3
- data/lib/ruhoh/routes.rb +8 -2
- data/lib/ruhoh/time.rb +10 -0
- data/lib/ruhoh/ui/page_not_found.html +103 -0
- data/lib/ruhoh/ui/page_not_found.rb +75 -0
- data/lib/ruhoh/version.rb +1 -1
- data/lib/ruhoh/views/helpers/simple_proxy.rb +37 -0
- data/lib/ruhoh/views/master_view.rb +11 -1
- data/system/widgets/analytics/google.html +1 -0
- data/system/widgets/syntax/prettify.html +13 -1
- metadata +14 -2
@@ -0,0 +1,41 @@
|
|
1
|
+
Feature: Date Formatting
|
2
|
+
As a content publisher
|
3
|
+
I want my dates to be formated correctly
|
4
|
+
so that I can ...
|
5
|
+
|
6
|
+
Scenario Outline: Date with configured date_format and correct dates
|
7
|
+
Given a config file with value:
|
8
|
+
"""
|
9
|
+
{ "date_format": "<date-format>" }
|
10
|
+
"""
|
11
|
+
And some files with values:
|
12
|
+
| file | date | body |
|
13
|
+
| _root/index.html | <date> | {{ page.date }} |
|
14
|
+
When I compile my site
|
15
|
+
Then my compiled site should have the file "index.html"
|
16
|
+
And this file should contain the content "<formated-date>"
|
17
|
+
Examples:
|
18
|
+
| date | date-format | formated-date |
|
19
|
+
| 2013-12-11 | %Y.%m | 2013.12 |
|
20
|
+
| 2012-01-1 | | |
|
21
|
+
| 1991.11.11 | %B %d, %Y | November 11, 1991 |
|
22
|
+
| 0-1-2 | %d/%m/%y | 02/01/00 |
|
23
|
+
|
24
|
+
|
25
|
+
Scenario: Date without a configured date_format
|
26
|
+
Given some files with values:
|
27
|
+
| file | date | body |
|
28
|
+
| _root/index.html | 2013.12.11 | {{ page.date }} |
|
29
|
+
When I compile my site
|
30
|
+
Then my compiled site should have the file "index.html"
|
31
|
+
And this file should contain the content "2013-12-11"
|
32
|
+
|
33
|
+
Scenario: Invalid date
|
34
|
+
Given some files with values:
|
35
|
+
| file | date | body |
|
36
|
+
| _root/index.html | 0-0 | {{ page.date }} |
|
37
|
+
When I try to compile my site
|
38
|
+
Then it should fail with:
|
39
|
+
"""
|
40
|
+
ArgumentError: The date '0-0' specified in 'index.html' is unparsable.
|
41
|
+
"""
|
data/features/step_defs.rb
CHANGED
@@ -2,6 +2,10 @@ Transform(/^(should|should NOT)$/) do |matcher|
|
|
2
2
|
matcher.downcase.gsub(' ', '_')
|
3
3
|
end
|
4
4
|
|
5
|
+
Given(/^a config file with value:$/) do |string|
|
6
|
+
make_config(JSON.parse(string))
|
7
|
+
end
|
8
|
+
|
5
9
|
Given(/^a config file with values:$/) do |table|
|
6
10
|
data = table.rows_hash
|
7
11
|
data.each{ |key, value| data[key] = JSON.parse(value) }
|
@@ -21,6 +25,27 @@ Given(/^some files with values:$/) do |table|
|
|
21
25
|
end
|
22
26
|
end
|
23
27
|
|
28
|
+
When(/^I try to compile my site$/) do
|
29
|
+
begin
|
30
|
+
compile
|
31
|
+
rescue Exception => e
|
32
|
+
@exception = e
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
Then(/^it should fail$/) do
|
37
|
+
@exception.should_not be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
Then(/^it (should|should NOT) fail with:$/) do |matcher, content|
|
41
|
+
@exception.should_not be_nil
|
42
|
+
Ruhoh.log.buffer.last.__send__(matcher, have_content(content))
|
43
|
+
end
|
44
|
+
|
45
|
+
Then(/^the log (should|should NOT) include:$/) do |matcher, content|
|
46
|
+
Ruhoh.log.buffer.__send__(matcher, include(content))
|
47
|
+
end
|
48
|
+
|
24
49
|
When(/^I compile my site$/) do
|
25
50
|
compile
|
26
51
|
end
|
data/history.json
CHANGED
@@ -1,4 +1,25 @@
|
|
1
1
|
[
|
2
|
+
{
|
3
|
+
"version" : "2.5",
|
4
|
+
"date" : "22.09.2013",
|
5
|
+
"features" : [
|
6
|
+
"@stebalien makes dates formattable",
|
7
|
+
"Add more helpful 404 not_found page for pages that don't exist.",
|
8
|
+
"Add support for `ruhoh server`; builtin web-server spawning.",
|
9
|
+
"Add gist view helper.",
|
10
|
+
"Add SimpleProxy helper object for views.",
|
11
|
+
"Allow converters to run on partials if file ext specified.",
|
12
|
+
"Add command line interface for publish.",
|
13
|
+
"@amanking add Google Analytics support for _setDomainName"
|
14
|
+
],
|
15
|
+
"bugs" : [
|
16
|
+
"Fix parse error when trying to parse empty file.",
|
17
|
+
"@douo Fix list command fail in verbose mode",
|
18
|
+
"@wwchen fix for drafts ommiting title via terminal.",
|
19
|
+
"@douo routes should trace all routable resources."
|
20
|
+
]
|
21
|
+
}
|
22
|
+
,
|
2
23
|
{
|
3
24
|
"version" : "2.4",
|
4
25
|
"date" : "10.09.2013",
|
data/lib/ruhoh.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
Encoding.default_internal = 'UTF-8'
|
3
3
|
require 'json'
|
4
4
|
require 'time'
|
5
|
+
require 'ruhoh/time'
|
5
6
|
require 'cgi'
|
6
7
|
require 'fileutils'
|
7
8
|
require 'ostruct'
|
@@ -81,6 +82,8 @@ class Ruhoh
|
|
81
82
|
config['base_path'] += "/" unless config['base_path'][-1] == '/'
|
82
83
|
end
|
83
84
|
|
85
|
+
Time.default_format = config['date_format'] || "%Y-%m-%d"
|
86
|
+
|
84
87
|
@config = config
|
85
88
|
end
|
86
89
|
|
@@ -233,7 +236,7 @@ class Ruhoh
|
|
233
236
|
dict[key] || dict.values.find{ |a| key == a['id'].gsub(/.[^.]+$/, '') }
|
234
237
|
end
|
235
238
|
|
236
|
-
# Collect all files from the base
|
239
|
+
# Collect all files from the base cascade directories.
|
237
240
|
# @return[Hash] dictionary of file pointers
|
238
241
|
def _all_files
|
239
242
|
dict = {}
|
data/lib/ruhoh/base/model.rb
CHANGED
@@ -66,7 +66,17 @@ module Ruhoh::Base
|
|
66
66
|
data['id'] = @pointer['id']
|
67
67
|
|
68
68
|
data['title'] = data['title'] || filename_data['title']
|
69
|
-
data['date'] ||= filename_data['date']
|
69
|
+
data['date'] ||= filename_data['date']
|
70
|
+
|
71
|
+
# Parse and store date as an object
|
72
|
+
begin
|
73
|
+
data['date'] = Time.parse(data['date']) unless data['date'].nil? || data['date'].is_a?(Time)
|
74
|
+
rescue
|
75
|
+
Ruhoh.log.error(
|
76
|
+
"ArgumentError: The date '#{data['date']}' specified in '#{@pointer['id']}' is unparsable."
|
77
|
+
)
|
78
|
+
data['date'] = nil
|
79
|
+
end
|
70
80
|
data['url'] = url(data)
|
71
81
|
data['layout'] = collection.config['layout'] if data['layout'].nil?
|
72
82
|
|
@@ -44,10 +44,7 @@ module Ruhoh::Base
|
|
44
44
|
this_data = __send__(attribute)
|
45
45
|
other_data = other.__send__(attribute)
|
46
46
|
if attribute == "date"
|
47
|
-
|
48
|
-
this_data = Time.parse(this_data.to_s)
|
49
|
-
other_data = Time.parse(other_data.to_s)
|
50
|
-
rescue ArgumentError, TypeError
|
47
|
+
if this_data.nil? || other_data.nil?
|
51
48
|
Ruhoh.log.error(
|
52
49
|
"ArgumentError:" +
|
53
50
|
" The '#{ @model.collection.resource_name }' collection is configured to sort based on 'date'" +
|
data/lib/ruhoh/client.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
|
1
3
|
require 'ruhoh/programs/compile'
|
2
4
|
require 'ruhoh/console_methods'
|
3
|
-
|
4
|
-
|
5
|
+
|
6
|
+
module Ruhoh::Publish; end
|
7
|
+
Dir[File.join(File.dirname(__FILE__), 'publish', '*.rb')].each { |f|
|
8
|
+
require f
|
9
|
+
}
|
5
10
|
|
6
11
|
class Ruhoh
|
7
12
|
|
@@ -16,6 +21,10 @@ class Ruhoh
|
|
16
21
|
"command" => "compile",
|
17
22
|
"desc" => "Compile to static website."
|
18
23
|
},
|
24
|
+
{
|
25
|
+
"command" => "publish <service>",
|
26
|
+
"desc" => "Publish site using a given service library"
|
27
|
+
},
|
19
28
|
{
|
20
29
|
"command" => "help",
|
21
30
|
"desc" => "Show this menu."
|
@@ -25,9 +34,12 @@ class Ruhoh
|
|
25
34
|
@args = data[:args]
|
26
35
|
@options = data[:options]
|
27
36
|
@opt_parser = data[:opt_parser]
|
28
|
-
|
37
|
+
|
29
38
|
cmd = (@args[0] == 'new') ? 'blog' : (@args[0] || 'help')
|
30
39
|
|
40
|
+
return server if %w(s serve server).include?(cmd)
|
41
|
+
|
42
|
+
@ruhoh = Ruhoh.new
|
31
43
|
@ruhoh.setup
|
32
44
|
@ruhoh.setup_paths
|
33
45
|
@ruhoh.setup_plugins
|
@@ -51,6 +63,7 @@ class Ruhoh
|
|
51
63
|
|
52
64
|
# Thanks rails! https://github.com/rails/rails/blob/master/railties/lib/rails/commands/console.rb
|
53
65
|
def console
|
66
|
+
require 'irb'
|
54
67
|
require 'pp'
|
55
68
|
Ruhoh::ConsoleMethods.env = @args[1]
|
56
69
|
IRB::ExtendCommandBundle.send :include, Ruhoh::ConsoleMethods
|
@@ -103,6 +116,37 @@ class Ruhoh
|
|
103
116
|
}
|
104
117
|
end
|
105
118
|
|
119
|
+
def server
|
120
|
+
require 'rack'
|
121
|
+
Rack::Server.start({
|
122
|
+
app: Ruhoh::Program.preview,
|
123
|
+
Port: (@args[1] || 9292)
|
124
|
+
})
|
125
|
+
end
|
126
|
+
alias_method :s, :server
|
127
|
+
alias_method :serve, :server
|
128
|
+
|
129
|
+
def publish
|
130
|
+
service = @args[1].to_s.downcase.capitalize
|
131
|
+
if service.empty?
|
132
|
+
Ruhoh::Friend.say {
|
133
|
+
red "Specify a publishing service"
|
134
|
+
exit
|
135
|
+
}
|
136
|
+
end
|
137
|
+
|
138
|
+
if Ruhoh::Publish.const_defined?(service.to_sym)
|
139
|
+
publish_config = Ruhoh::Parse.data_file(@ruhoh.base, "publish") || {}
|
140
|
+
Ruhoh::Publish.const_get(service.to_sym).new.run(@args, publish_config[service.downcase])
|
141
|
+
else
|
142
|
+
Ruhoh::Friend.say {
|
143
|
+
red "'#{ service }' not found."
|
144
|
+
plain "Ensure the service class is properly namespaced at Ruhoh::Publish::#{ service }"
|
145
|
+
exit
|
146
|
+
}
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
106
150
|
# Public: Create a new blog at the directory provided.
|
107
151
|
def blog
|
108
152
|
name = @args[1]
|
data/lib/ruhoh/parse.rb
CHANGED
@@ -3,7 +3,7 @@ class Ruhoh
|
|
3
3
|
# Public: A program for compiling to a static website.
|
4
4
|
# The compile environment should always be 'production' in order
|
5
5
|
# to properly omit drafts and other development-only settings.
|
6
|
-
def self.compile(target)
|
6
|
+
def self.compile(target=nil)
|
7
7
|
ruhoh = Ruhoh.new
|
8
8
|
ruhoh.setup
|
9
9
|
ruhoh.env = 'production'
|
@@ -15,8 +15,10 @@ class Ruhoh
|
|
15
15
|
elsif ruhoh.config["compiled"]
|
16
16
|
ruhoh.paths.compiled = ruhoh.config["compiled"]
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
ruhoh.compile
|
20
|
+
|
21
|
+
ruhoh
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Ruhoh
|
2
|
+
class Publish::Rsync
|
3
|
+
# Deploy via rsync
|
4
|
+
# @param[opts] - CLI arguments
|
5
|
+
# @param[config] - config hash supplied from publish.yml or publish.json
|
6
|
+
#
|
7
|
+
# Example publish.json file:
|
8
|
+
# {
|
9
|
+
# "rsync": {
|
10
|
+
# "command": nil,
|
11
|
+
# "user": "root",
|
12
|
+
# "host": "12.345.67.891",
|
13
|
+
# "destination": "/var/www/my-site.com"
|
14
|
+
# }
|
15
|
+
# }
|
16
|
+
#
|
17
|
+
# Use "command" to specify a customized rsync command to execute.
|
18
|
+
def run(opts={}, config={})
|
19
|
+
@config = config
|
20
|
+
ruhoh = Ruhoh::Program.compile
|
21
|
+
|
22
|
+
if @config["command"]
|
23
|
+
system(@config["command"])
|
24
|
+
else
|
25
|
+
system('rsync', File.join(ruhoh.paths.compiled, '.'), '-avz', '--delete', '--exclude', '.git', remote)
|
26
|
+
end
|
27
|
+
FileUtils.rm_r(ruhoh.paths.compiled)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def remote
|
33
|
+
"#{ @config["user"] }@#{ @config["host"] }:#{ @config["destination"] }"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -67,7 +67,7 @@ module Ruhoh::Resources::Pages
|
|
67
67
|
def render_scaffold
|
68
68
|
(@collection.scaffold || '')
|
69
69
|
.gsub('{{DATE}}', Time.now.strftime('%Y-%m-%d'))
|
70
|
-
.gsub('{{TITLE}}', @args[2])
|
70
|
+
.gsub('{{TITLE}}', (@args[2] || ''))
|
71
71
|
end
|
72
72
|
|
73
73
|
protected
|
@@ -116,7 +116,7 @@ module Ruhoh::Resources::Pages
|
|
116
116
|
def _list(data)
|
117
117
|
if @options.verbose
|
118
118
|
Ruhoh::Friend.say {
|
119
|
-
data.
|
119
|
+
data.each do |p|
|
120
120
|
cyan("- #{p['id']}")
|
121
121
|
plain(" title: #{p['title']}")
|
122
122
|
plain(" url: #{p['url']}")
|
@@ -41,11 +41,11 @@ module Ruhoh::Resources::Pages
|
|
41
41
|
collated = []
|
42
42
|
pages = all
|
43
43
|
pages.each_with_index do |page, i|
|
44
|
-
thisYear =
|
45
|
-
thisMonth =
|
44
|
+
thisYear = page['date'].strftime('%Y')
|
45
|
+
thisMonth = page['date'].strftime('%B')
|
46
46
|
if (i-1 >= 0)
|
47
|
-
prevYear =
|
48
|
-
prevMonth =
|
47
|
+
prevYear = pages[i-1]['date'].strftime('%Y')
|
48
|
+
prevMonth = pages[i-1]['date'].strftime('%B')
|
49
49
|
end
|
50
50
|
|
51
51
|
if(prevYear == thisYear)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'ruhoh/ui/page_not_found'
|
1
2
|
# Public: Rack application used to render singular pages via their URL.
|
2
3
|
module Ruhoh::Resources::Pages
|
3
4
|
class Previewer
|
@@ -23,16 +24,7 @@ module Ruhoh::Resources::Pages
|
|
23
24
|
if view
|
24
25
|
[200, {'Content-Type' => 'text/html'}, [view.render_full]]
|
25
26
|
else
|
26
|
-
|
27
|
-
" using file pointer: '#{ pointer.inspect }'."
|
28
|
-
|
29
|
-
if pointer.nil?
|
30
|
-
message += " Since the file pointer was nil" +
|
31
|
-
" we tried to load a pagination view but it didn't work;" +
|
32
|
-
"\n Expected the format to be: '<valid_resource_name>/page_number'"
|
33
|
-
end
|
34
|
-
|
35
|
-
raise message
|
27
|
+
Ruhoh::UI::PageNotFound.new(@ruhoh, pointer).call(env)
|
36
28
|
end
|
37
29
|
end
|
38
30
|
|
@@ -70,4 +62,4 @@ module Ruhoh::Resources::Pages
|
|
70
62
|
[200, {'Content-Type' => 'image/x-icon'}, ['']]
|
71
63
|
end
|
72
64
|
end
|
73
|
-
end
|
65
|
+
end
|
@@ -3,9 +3,8 @@ module Ruhoh::Resources::Partials
|
|
3
3
|
include Ruhoh::Base::Modelable
|
4
4
|
|
5
5
|
def process
|
6
|
-
|
7
|
-
|
8
|
-
}
|
6
|
+
content = File.open(@pointer['realpath'], 'r:UTF-8') { |f| f.read }
|
7
|
+
Ruhoh::Converter.convert(content, @pointer['id'])
|
9
8
|
end
|
10
9
|
end
|
11
10
|
end
|
data/lib/ruhoh/routes.rb
CHANGED
@@ -5,7 +5,7 @@ class Ruhoh
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def find(route)
|
8
|
-
|
8
|
+
routable.each do |r|
|
9
9
|
next unless @ruhoh.collection(r).routes[route]
|
10
10
|
return @ruhoh.collection(r).routes[route]
|
11
11
|
break
|
@@ -20,10 +20,16 @@ class Ruhoh
|
|
20
20
|
# @returns[Hash map]
|
21
21
|
def all
|
22
22
|
routes = {}
|
23
|
-
|
23
|
+
routable.each do |r|
|
24
24
|
routes.merge!(@ruhoh.collection(r).routes)
|
25
25
|
end
|
26
26
|
routes
|
27
27
|
end
|
28
|
+
|
29
|
+
def routable
|
30
|
+
@ruhoh.collections.all.keep_if do |r|
|
31
|
+
@ruhoh.collections.collection(r).include?(Ruhoh::Resources::Pages::Routable) rescue false
|
32
|
+
end
|
33
|
+
end
|
28
34
|
end
|
29
35
|
end
|
data/lib/ruhoh/time.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<style>
|
6
|
+
html, body {
|
7
|
+
margin:0;
|
8
|
+
padding:0;
|
9
|
+
font-family: monospace;
|
10
|
+
color: #424254;
|
11
|
+
}
|
12
|
+
h1, h2, h3, h4, h5 {
|
13
|
+
line-height: 1.2em;
|
14
|
+
}
|
15
|
+
div, p, ul {
|
16
|
+
line-height: 1.5em;
|
17
|
+
}
|
18
|
+
textarea {
|
19
|
+
display:block;
|
20
|
+
height:250px;
|
21
|
+
width:100%;
|
22
|
+
padding:0;
|
23
|
+
border:1px solid #ccc;
|
24
|
+
}
|
25
|
+
button {
|
26
|
+
font-size:1.4em;
|
27
|
+
width:100%;
|
28
|
+
padding:5px;
|
29
|
+
cursor: pointer;
|
30
|
+
}
|
31
|
+
|
32
|
+
#wrapper {
|
33
|
+
padding:20px;
|
34
|
+
}
|
35
|
+
.pane {
|
36
|
+
display:inline-block;
|
37
|
+
width:45%;
|
38
|
+
vertical-align: top;
|
39
|
+
}
|
40
|
+
.error {
|
41
|
+
color: #CC2A41;
|
42
|
+
}
|
43
|
+
#heading {
|
44
|
+
background-color: #CC2A41;
|
45
|
+
color:#FFF;
|
46
|
+
padding: 10px 20px;
|
47
|
+
margin:0;
|
48
|
+
font-weight: normal;
|
49
|
+
}
|
50
|
+
.success {
|
51
|
+
background-color: #64908A;
|
52
|
+
color:#FFF;
|
53
|
+
border:0;
|
54
|
+
}
|
55
|
+
.success:hover {
|
56
|
+
background-color: hsl(172, 18%, 38%)
|
57
|
+
}
|
58
|
+
pre, code {
|
59
|
+
background-color: #eee;
|
60
|
+
padding:3px;
|
61
|
+
}
|
62
|
+
</style>
|
63
|
+
<head>
|
64
|
+
</body>
|
65
|
+
<h1 id="heading">o_O | No generated page URL matches: {{ url }}</h1>
|
66
|
+
<div id="wrapper">
|
67
|
+
<p>
|
68
|
+
{{# pointer }}
|
69
|
+
Using file pointer:
|
70
|
+
<br>
|
71
|
+
<code>{{ pointer.inspect }}</code>
|
72
|
+
{{/ pointer }}
|
73
|
+
</p>
|
74
|
+
|
75
|
+
<p>
|
76
|
+
<strong class="error">NOTE:</strong>
|
77
|
+
<strong>{{ filepath }}</strong> <em>probably</em> represents this URL. We can't be sure as you may have set custom permalinks,
|
78
|
+
<br>but we figure we'd try to help anyway. This service will get better in time ^_^!
|
79
|
+
</p>
|
80
|
+
<div class="pane" style="margin-right:3%">
|
81
|
+
<h2>Create Page Automatically:</h2>
|
82
|
+
<form method="POST">
|
83
|
+
<textarea name="body">{{ content }}</textarea>
|
84
|
+
<button type="submit" class="success">YES - create {{ filepath }} now.</button>
|
85
|
+
</form>
|
86
|
+
</div>
|
87
|
+
|
88
|
+
<div class="pane">
|
89
|
+
<h2>Create Page Manually:</h2>
|
90
|
+
<pre><code>{{ filepath }}</code></pre>
|
91
|
+
|
92
|
+
<p>Write some sample markdown inside the file:</p>
|
93
|
+
<pre><code>{{ content }}</code></pre>
|
94
|
+
|
95
|
+
<p>
|
96
|
+
Save changes and reload the page: <a href="{{ url }}">{{ url }}</a>
|
97
|
+
<br>You should see the updated content =D.
|
98
|
+
</p>
|
99
|
+
</div>
|
100
|
+
|
101
|
+
</div>
|
102
|
+
</body>
|
103
|
+
</html>
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Ruhoh::UI
|
2
|
+
class PageNotFound
|
3
|
+
Content = <<-TEXT
|
4
|
+
# Hello World =D
|
5
|
+
|
6
|
+
> A profound quote.
|
7
|
+
|
8
|
+
### Fruits I like
|
9
|
+
|
10
|
+
- apples
|
11
|
+
- oranges
|
12
|
+
- watermelons
|
13
|
+
- tomatoes
|
14
|
+
- avocados
|
15
|
+
TEXT
|
16
|
+
|
17
|
+
def initialize(ruhoh, pointer)
|
18
|
+
@ruhoh = ruhoh
|
19
|
+
@pointer = pointer
|
20
|
+
end
|
21
|
+
|
22
|
+
def call(env)
|
23
|
+
@request = Rack::Request.new(env)
|
24
|
+
@request.post? ? create : show
|
25
|
+
end
|
26
|
+
|
27
|
+
def show
|
28
|
+
template = File.open(File.join(File.dirname(__FILE__), 'page_not_found.html'), 'r:UTF-8').read
|
29
|
+
body = Mustache.render(template, {
|
30
|
+
pointer: @pointer,
|
31
|
+
url: @request.path,
|
32
|
+
filepath: File.join(File.basename(@ruhoh.base), filepath),
|
33
|
+
content: Content
|
34
|
+
})
|
35
|
+
|
36
|
+
[404, {'Content-Type' => 'text/html'}, [body]]
|
37
|
+
end
|
38
|
+
|
39
|
+
def create
|
40
|
+
FileUtils.mkdir_p File.dirname(filepath)
|
41
|
+
File.open(filepath, 'w:UTF-8') { |f| f.puts @request.params["body"] }
|
42
|
+
|
43
|
+
sleep 2 # wait for the watcher to pick up the changes (terrible i know)
|
44
|
+
|
45
|
+
response = Rack::Response.new
|
46
|
+
response.redirect @request.path
|
47
|
+
status, header, body = response.finish
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# Determine the correct filepath from the URL structure.
|
53
|
+
# TODO: This if very rudimentary and only works for a stock configuration.
|
54
|
+
def filepath
|
55
|
+
parts = @request.path.split('/')
|
56
|
+
parts.shift # omit root forward slash
|
57
|
+
|
58
|
+
path = (parts.length <= 1) ?
|
59
|
+
File.join("_root", (parts.empty? ? "index" : parts.first)) :
|
60
|
+
File.join(*parts) # collection
|
61
|
+
|
62
|
+
File.extname(parts.last.to_s).to_s.empty? ?
|
63
|
+
(path + @ruhoh.collection(collection_name).config["ext"]) :
|
64
|
+
path
|
65
|
+
end
|
66
|
+
|
67
|
+
def collection_name
|
68
|
+
parts = @request.path.split('/')
|
69
|
+
parts.shift # omit root forward slash
|
70
|
+
|
71
|
+
(parts.length <= 1) ? "_root" : parts.first
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
data/lib/ruhoh/version.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Ruhoh::Views::Helpers
|
2
|
+
# Simple proxy object used to responsd to arbitary method calls on an explicit receiver in views.
|
3
|
+
#
|
4
|
+
# Example:
|
5
|
+
#
|
6
|
+
# def gist
|
7
|
+
# SimpleProxy.new({
|
8
|
+
# matcher: /^[0-9]+$/,
|
9
|
+
# function: -> input {
|
10
|
+
# "<script src=\"https://gist.github.com/#{ input }.js\"></script>"
|
11
|
+
# }
|
12
|
+
# })
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# Usage:
|
16
|
+
#
|
17
|
+
# {{{ gist.12345 }}}
|
18
|
+
#
|
19
|
+
# The method "12345" is matched against "matcher" and provided to "function" on success.
|
20
|
+
class SimpleProxy
|
21
|
+
# @param[opts] Hash
|
22
|
+
# - opts[:matcher] A regular expression to match method calls against.
|
23
|
+
# - opts[:function] The function to execute when successfully called.
|
24
|
+
# The function takes the name of the method as the input.
|
25
|
+
def initialize(opts)
|
26
|
+
@opts = opts
|
27
|
+
end
|
28
|
+
|
29
|
+
def method_missing(name, *args, &block)
|
30
|
+
@opts[:function].call(name.to_s)
|
31
|
+
end
|
32
|
+
|
33
|
+
def respond_to?(method)
|
34
|
+
method.to_s.match(@opts[:matcher]).nil? ? super : true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'ruhoh/views/rmustache'
|
2
|
+
require 'ruhoh/views/helpers/simple_proxy'
|
2
3
|
|
3
4
|
module Ruhoh::Views
|
4
5
|
module Helpers ; end
|
@@ -103,7 +104,16 @@ module Ruhoh::Views
|
|
103
104
|
def to_slug(sub_context)
|
104
105
|
Ruhoh::StringFormat.clean_slug(sub_context)
|
105
106
|
end
|
106
|
-
|
107
|
+
|
108
|
+
def gist
|
109
|
+
@gist ||= Ruhoh::Views::Helpers::SimpleProxy.new({
|
110
|
+
matcher: /^[0-9]+$/,
|
111
|
+
function: -> input {
|
112
|
+
"<script src=\"https://gist.github.com/#{ input }.js\"></script>"
|
113
|
+
}
|
114
|
+
})
|
115
|
+
end
|
116
|
+
|
107
117
|
# Public: Formats the path to the compiled file based on the URL.
|
108
118
|
#
|
109
119
|
# Returns: [String] The relative path to the compiled file for this page.
|
@@ -7,6 +7,7 @@ tracking_id : 'UA-123-12'
|
|
7
7
|
var _gaq = _gaq || [];
|
8
8
|
_gaq.push(['_setAccount', '{{ this_config.tracking_id }}']);
|
9
9
|
_gaq.push(['_trackPageview']);
|
10
|
+
{{# this_config.domain_name }}_gaq.push(['_setDomainName', '{{ . }}']);{{/ this_config.domain_name }}
|
10
11
|
|
11
12
|
(function() {
|
12
13
|
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
@@ -10,8 +10,20 @@ cdn:
|
|
10
10
|
{{^ this_config.cdn.enable }}<script src="{{this_path}}/javascripts/prettify.js"></script>{{/ this_config.cdn.enable }}
|
11
11
|
<script>
|
12
12
|
var pres = document.getElementsByTagName("pre");
|
13
|
+
var is_gist_present = document.getElementsByClassName("gist"); is_gist_present = is_gist_present.length > 0;
|
14
|
+
|
13
15
|
for (var i=0; i < pres.length; ++i) {
|
14
|
-
|
16
|
+
var is_valid;
|
17
|
+
if(is_gist_present) {
|
18
|
+
is_valid = pres[i].getElementsByTagName("code");
|
19
|
+
is_valid = (is_valid.length > 0);
|
20
|
+
} else {
|
21
|
+
is_valid = true;
|
22
|
+
}
|
23
|
+
|
24
|
+
if(is_valid) {
|
25
|
+
pres[i].className = "prettyprint {{# this_config.linenums }}linenums{{/this_config.linenums}}";
|
26
|
+
}
|
15
27
|
}
|
16
28
|
prettyPrint();
|
17
29
|
</script>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruhoh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '2.
|
4
|
+
version: '2.5'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-09-
|
12
|
+
date: 2013-09-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -156,6 +156,7 @@ files:
|
|
156
156
|
- features/config.feature
|
157
157
|
- features/conversion.feature
|
158
158
|
- features/data.feature
|
159
|
+
- features/date_format.feature
|
159
160
|
- features/drafts.feature
|
160
161
|
- features/ignore.feature
|
161
162
|
- features/javascripts.feature
|
@@ -194,6 +195,7 @@ files:
|
|
194
195
|
- lib/ruhoh/programs/compile.rb
|
195
196
|
- lib/ruhoh/programs/preview.rb
|
196
197
|
- lib/ruhoh/programs/watch.rb
|
198
|
+
- lib/ruhoh/publish/rsync.rb
|
197
199
|
- lib/ruhoh/resources/dash/collection.rb
|
198
200
|
- lib/ruhoh/resources/dash/model.rb
|
199
201
|
- lib/ruhoh/resources/dash/model_view.rb
|
@@ -230,11 +232,15 @@ files:
|
|
230
232
|
- lib/ruhoh/routes.rb
|
231
233
|
- lib/ruhoh/string_format.rb
|
232
234
|
- lib/ruhoh/summarizer.rb
|
235
|
+
- lib/ruhoh/time.rb
|
236
|
+
- lib/ruhoh/ui/page_not_found.html
|
237
|
+
- lib/ruhoh/ui/page_not_found.rb
|
233
238
|
- lib/ruhoh/url_slug.rb
|
234
239
|
- lib/ruhoh/utils.rb
|
235
240
|
- lib/ruhoh/version.rb
|
236
241
|
- lib/ruhoh/views/helpers/categories.rb
|
237
242
|
- lib/ruhoh/views/helpers/paginator.rb
|
243
|
+
- lib/ruhoh/views/helpers/simple_proxy.rb
|
238
244
|
- lib/ruhoh/views/helpers/tags.rb
|
239
245
|
- lib/ruhoh/views/master_view.rb
|
240
246
|
- lib/ruhoh/views/rmustache.rb
|
@@ -277,12 +283,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
277
283
|
- - ! '>='
|
278
284
|
- !ruby/object:Gem::Version
|
279
285
|
version: '0'
|
286
|
+
segments:
|
287
|
+
- 0
|
288
|
+
hash: 4393455842480950745
|
280
289
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
281
290
|
none: false
|
282
291
|
requirements:
|
283
292
|
- - ! '>='
|
284
293
|
- !ruby/object:Gem::Version
|
285
294
|
version: '0'
|
295
|
+
segments:
|
296
|
+
- 0
|
297
|
+
hash: 4393455842480950745
|
286
298
|
requirements: []
|
287
299
|
rubyforge_project:
|
288
300
|
rubygems_version: 1.8.24
|