pith 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +106 -14
- data/bin/pith +8 -1
- data/features/helpers.feature +28 -0
- data/features/step_definitions/build_steps.rb +4 -0
- data/features/step_definitions/build_steps.rb~ +4 -0
- data/lib/pith/input/template.rb +3 -7
- data/lib/pith/input/template.rb~ +3 -3
- data/lib/pith/project.rb +8 -1
- data/lib/pith/project.rb~ +8 -1
- data/lib/pith/render_context.rb +4 -4
- data/lib/pith/render_context.rb~ +12 -5
- data/lib/pith/version.rb +1 -1
- data/lib/pith/version.rb~ +1 -1
- metadata +4 -4
data/README.markdown
CHANGED
@@ -1,28 +1,21 @@
|
|
1
1
|
Pith
|
2
2
|
====
|
3
3
|
|
4
|
-
Pith is a static
|
4
|
+
Pith is a static website generator, written in Ruby.
|
5
5
|
|
6
6
|
Using Pith, you can:
|
7
7
|
|
8
|
-
*
|
8
|
+
* Lay-out your page designs in [Haml][haml], ERb, or Liquid.
|
9
9
|
|
10
|
-
*
|
10
|
+
* Style things up using [Sass][sass].
|
11
11
|
|
12
|
-
*
|
12
|
+
* Succintly add content using Markdown or Textile.
|
13
13
|
|
14
|
-
*
|
14
|
+
* Encapsulate common markup in "layout" and "partial" templates.
|
15
15
|
|
16
|
-
*
|
16
|
+
* Easily link pages (and resources) using relative links.
|
17
17
|
|
18
|
-
*
|
19
|
-
|
20
|
-
* __Define custom helper-methods__ to increase expressiveness.
|
21
|
-
|
22
|
-
Why Pith?
|
23
|
-
---------
|
24
|
-
|
25
|
-
Why another static web-site generator, when there are other good options out there? Pith's main differentiating factor is that structure of the output slavishly mirrors the structure of the input; there are no magic input directories for layouts, or dynamic content, or anything else.
|
18
|
+
* Test changes quickly using the built-in web-server.
|
26
19
|
|
27
20
|
Install it
|
28
21
|
----------
|
@@ -31,6 +24,105 @@ Pith is packaged as a Ruby gem. Assuming you have Ruby, install it thusly:
|
|
31
24
|
|
32
25
|
gem install pith
|
33
26
|
|
27
|
+
Quickstart
|
28
|
+
----------
|
29
|
+
|
30
|
+
Create an input directory for your site (wherever you want), and pop some files into it:
|
31
|
+
|
32
|
+
SITE/
|
33
|
+
_pith/
|
34
|
+
images/
|
35
|
+
logo.png
|
36
|
+
index.html.haml
|
37
|
+
|
38
|
+
The only requirement is the existance of a sub-directory called "`_pith`". Pith checks that it's present, to prevent you accidently treating you entire home-directory as website input.
|
39
|
+
|
40
|
+
Next, use the `pith build` command to convert your inputs into a functioning website.
|
41
|
+
|
42
|
+
$ pith -i SITE build
|
43
|
+
Generating to "SITE/_out"
|
44
|
+
--(copy)--> images/logo.png
|
45
|
+
--(haml)--> index.html
|
46
|
+
|
47
|
+
Any input file with an extension recognised by [Tilt][tilt] is considered to be a template, and will be dynamically evaluated. Formats supported by Tilt include:
|
48
|
+
|
49
|
+
- [Markdown](http://daringfireball.net/projects/markdown/) (`markdown`, `md`)
|
50
|
+
- [Textile](http://redcloth.org/hobix.com/textile/) (`textile`)
|
51
|
+
- [Haml][haml] (`haml`)
|
52
|
+
- [Erb](http://ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html) (`erb`)
|
53
|
+
- [Sass][sass] (`sass`)
|
54
|
+
- [CoffeeScript](http://jashkenas.github.com/coffee-script/) (`coffee`)
|
55
|
+
|
56
|
+
Anything else is just copied verbatim into the generated site.
|
57
|
+
|
58
|
+
Partials
|
59
|
+
--------
|
60
|
+
|
61
|
+
Templates can include other templates, e.g.
|
62
|
+
|
63
|
+
= include("_header.haml")
|
64
|
+
|
65
|
+
Note the leading underscore ("_"). Any input file (or directory) beginning with an underscore is ignored when generating outputs.
|
66
|
+
|
67
|
+
When including, you can pass local variables, e.g.
|
68
|
+
|
69
|
+
= include("_list.haml", :items => [1,2,3])
|
70
|
+
|
71
|
+
which can be accessed in the included template:
|
72
|
+
|
73
|
+
%ul
|
74
|
+
- items.each do |i|
|
75
|
+
%li= i
|
76
|
+
|
77
|
+
Layouts
|
78
|
+
-------
|
79
|
+
|
80
|
+
Layout templates are a bit like partials, except that they take a block, e.g.
|
81
|
+
|
82
|
+
= inside "_mylayout.haml" do
|
83
|
+
%p Some content
|
84
|
+
|
85
|
+
Use "`yield`" to embed the block's content within the layout:
|
86
|
+
|
87
|
+
!!!
|
88
|
+
%html
|
89
|
+
%body
|
90
|
+
.header
|
91
|
+
... blah blah ...
|
92
|
+
.main
|
93
|
+
= yield
|
94
|
+
|
95
|
+
Relative links
|
96
|
+
--------------
|
97
|
+
|
98
|
+
It's sensible to use relative URIs when linking to other pages (and resources) in your static site, making the site easier to relocate. But generating relative-links from partials and layouts is tricky. Pith makes it easy with the "`href`" function:
|
99
|
+
|
100
|
+
%a{:href => href("other.html")} Other page
|
101
|
+
|
102
|
+
%img{:src => href("/images/logo.png")}
|
103
|
+
|
104
|
+
Any path beginning with a slash ("/") is resolved relative to the root of the site; anything else is resolve relative to the current input-file (even if that happens to be a layout or partial). Either way, "`href`" always returns a relative link.
|
105
|
+
|
106
|
+
There's also a "`link`" function, for even easier hyper-linking:
|
107
|
+
|
108
|
+
link("other.html", "Other page")
|
109
|
+
|
110
|
+
Built-in web-server
|
111
|
+
-------------------
|
112
|
+
|
113
|
+
For quick prototyping, pith includes a simple HTTP server. Start it by using the "`serve`" command, rather than "`build`"
|
114
|
+
|
115
|
+
$ pith -i SITE serve
|
116
|
+
Generating to "SITE/_out"
|
117
|
+
--(copy)--> images/logo.png
|
118
|
+
--(haml)--> index.html
|
119
|
+
Taking the Pith at "http://localhost:4321"
|
120
|
+
>> Thin web server (v1.2.7 codename No Hup)
|
121
|
+
>> Maximum connections set to 1024
|
122
|
+
>> Listening on 0.0.0.0:4321, CTRL+C to stop
|
123
|
+
|
124
|
+
Pith will incrementally re-build the site as you browse -- that is, if you alter any input files, Pith will regenerate the affected outputs.
|
125
|
+
|
34
126
|
[tilt]: http://github.com/rtomayko/tilt/
|
35
127
|
[haml]: http://haml-lang.com
|
36
128
|
[sass]: http://sass-lang.com
|
data/bin/pith
CHANGED
@@ -36,9 +36,14 @@ OptionParser.new do |opts|
|
|
36
36
|
end
|
37
37
|
end.parse!
|
38
38
|
|
39
|
+
pith_dir = $input_dir + "_pith"
|
40
|
+
unless pith_dir.directory?
|
41
|
+
$stderr.puts %(ERROR: No "#{pith_dir}" directory ... this doesn't look right!)
|
42
|
+
exit(1)
|
43
|
+
end
|
44
|
+
|
39
45
|
unless $output_dir
|
40
46
|
$output_dir = $input_dir + "_out"
|
41
|
-
puts %{Generating to "#{$output_dir}"}
|
42
47
|
end
|
43
48
|
|
44
49
|
require "pith/project"
|
@@ -48,12 +53,14 @@ require "pith/console_logger"
|
|
48
53
|
@project.logger = Pith::ConsoleLogger.new
|
49
54
|
|
50
55
|
def build
|
56
|
+
puts %{Generating to "#{$output_dir}"}
|
51
57
|
@project.build
|
52
58
|
end
|
53
59
|
|
54
60
|
def serve
|
55
61
|
require "pith/server"
|
56
62
|
port = 4321
|
63
|
+
build
|
57
64
|
puts %{Taking the Pith at "http://localhost:#{port}"}
|
58
65
|
Pith::Server.run(@project, :Port => port)
|
59
66
|
end
|
data/features/helpers.feature
CHANGED
@@ -21,3 +21,31 @@ Scenario: call a helper from a template
|
|
21
21
|
When I build the site
|
22
22
|
|
23
23
|
Then output file "index.html" should contain "Hello, World"
|
24
|
+
|
25
|
+
Scenario: change a helper
|
26
|
+
|
27
|
+
Given input file "_pith/config.rb" contains
|
28
|
+
"""
|
29
|
+
project.helpers do
|
30
|
+
def greet(subject)
|
31
|
+
"Hello, #{subject}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
"""
|
35
|
+
|
36
|
+
And input file "index.html.haml" contains "= greet('mate')"
|
37
|
+
|
38
|
+
When I build the site
|
39
|
+
|
40
|
+
And I change input file "_pith/config.rb" to contain
|
41
|
+
"""
|
42
|
+
project.helpers do
|
43
|
+
def greet(subject)
|
44
|
+
"Gidday, #{subject}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
"""
|
48
|
+
|
49
|
+
And I rebuild the site
|
50
|
+
|
51
|
+
Then output file "index.html" should contain "Gidday, mate"
|
@@ -18,6 +18,10 @@ When /^I change input file "([^\"]*)" to contain "([^\"]*)"$/ do |path, content|
|
|
18
18
|
@inputs[path] = content
|
19
19
|
end
|
20
20
|
|
21
|
+
When /^I change input file "([^\"]*)" to contain$/ do |path, content|
|
22
|
+
@inputs[path] = content
|
23
|
+
end
|
24
|
+
|
21
25
|
When /^I (?:re)?build the site$/ do
|
22
26
|
@project.logger.clear
|
23
27
|
@project.build
|
@@ -18,6 +18,10 @@ When /^I change input file "([^\"]*)" to contain "([^\"]*)"$/ do |path, content|
|
|
18
18
|
@inputs[path] = content
|
19
19
|
end
|
20
20
|
|
21
|
+
When /^I change input file "([^\"]*)" to contain$/ do |path, content|
|
22
|
+
@inputs[path] = content
|
23
|
+
end
|
24
|
+
|
21
25
|
When /^I (?:re)?build the site$/ do
|
22
26
|
@project.logger.clear
|
23
27
|
@project.build
|
data/lib/pith/input/template.rb
CHANGED
@@ -28,7 +28,7 @@ module Pith
|
|
28
28
|
# Return true unless output needs to be re-generated.
|
29
29
|
#
|
30
30
|
def uptodate?
|
31
|
-
|
31
|
+
dependencies && FileUtils.uptodate?(output_file, dependencies)
|
32
32
|
end
|
33
33
|
|
34
34
|
# Generate output for this template
|
@@ -39,7 +39,7 @@ module Pith
|
|
39
39
|
output_file.open("w") do |out|
|
40
40
|
out.puts(render_context.render(self))
|
41
41
|
end
|
42
|
-
|
42
|
+
@dependencies = render_context.dependencies
|
43
43
|
end
|
44
44
|
|
45
45
|
# Render this input using Tilt
|
@@ -112,11 +112,7 @@ module Pith
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
-
|
116
|
-
@all_input_files = referenced_inputs.map { |input| input.file }
|
117
|
-
end
|
118
|
-
|
119
|
-
attr_accessor :all_input_files
|
115
|
+
attr_accessor :dependencies
|
120
116
|
|
121
117
|
end
|
122
118
|
|
data/lib/pith/input/template.rb~
CHANGED
@@ -39,7 +39,7 @@ module Pith
|
|
39
39
|
output_file.open("w") do |out|
|
40
40
|
out.puts(render_context.render(self))
|
41
41
|
end
|
42
|
-
remember_dependencies(render_context.
|
42
|
+
remember_dependencies(render_context.referenced_inputs)
|
43
43
|
end
|
44
44
|
|
45
45
|
# Render this input using Tilt
|
@@ -112,8 +112,8 @@ module Pith
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
-
def remember_dependencies(
|
116
|
-
@all_input_files =
|
115
|
+
def remember_dependencies(referenced_inputs)
|
116
|
+
@all_input_files = referenced_inputs.map { |input| input.file }
|
117
117
|
end
|
118
118
|
|
119
119
|
attr_accessor :all_input_files
|
data/lib/pith/project.rb
CHANGED
@@ -59,6 +59,7 @@ module Pith
|
|
59
59
|
#
|
60
60
|
def refresh
|
61
61
|
@inputs = nil
|
62
|
+
@config_files = nil
|
62
63
|
end
|
63
64
|
|
64
65
|
def logger
|
@@ -74,6 +75,12 @@ module Pith
|
|
74
75
|
def helper_module
|
75
76
|
@helper_module ||= Module.new
|
76
77
|
end
|
78
|
+
|
79
|
+
def config_files
|
80
|
+
@config_files ||= begin
|
81
|
+
Pathname.glob("#{input_dir}/_pith/**")
|
82
|
+
end.to_set
|
83
|
+
end
|
77
84
|
|
78
85
|
private
|
79
86
|
|
@@ -84,7 +91,7 @@ module Pith
|
|
84
91
|
eval(config_file.read, binding, config_file)
|
85
92
|
end
|
86
93
|
end
|
87
|
-
|
94
|
+
|
88
95
|
def input_cache
|
89
96
|
@input_cache ||= Hash.new do |h, cache_key|
|
90
97
|
h[cache_key] = Input.new(self, cache_key.first)
|
data/lib/pith/project.rb~
CHANGED
@@ -59,6 +59,7 @@ module Pith
|
|
59
59
|
#
|
60
60
|
def refresh
|
61
61
|
@inputs = nil
|
62
|
+
@config_files = nil
|
62
63
|
end
|
63
64
|
|
64
65
|
def logger
|
@@ -74,6 +75,12 @@ module Pith
|
|
74
75
|
def helper_module
|
75
76
|
@helper_module ||= Module.new
|
76
77
|
end
|
78
|
+
|
79
|
+
def config_files
|
80
|
+
@config_files ||= begin
|
81
|
+
Pathname.glob("#{input_dir}/_pith/**")
|
82
|
+
end.to_set
|
83
|
+
end
|
77
84
|
|
78
85
|
private
|
79
86
|
|
@@ -84,7 +91,7 @@ module Pith
|
|
84
91
|
eval(config_file.read, binding, config_file)
|
85
92
|
end
|
86
93
|
end
|
87
|
-
|
94
|
+
|
88
95
|
def input_cache
|
89
96
|
@input_cache ||= Hash.new do |h, cache_key|
|
90
97
|
h[cache_key] = Input.new(self, cache_key.first)
|
data/lib/pith/render_context.rb
CHANGED
@@ -11,7 +11,7 @@ module Pith
|
|
11
11
|
def initialize(project)
|
12
12
|
@project = project
|
13
13
|
@input_stack = []
|
14
|
-
@
|
14
|
+
@dependencies = project.config_files.dup
|
15
15
|
self.extend(project.helper_module)
|
16
16
|
end
|
17
17
|
|
@@ -34,7 +34,7 @@ module Pith
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
attr_reader :
|
37
|
+
attr_reader :dependencies
|
38
38
|
|
39
39
|
def include(template_ref, locals = {}, &block)
|
40
40
|
content_block = if block_given?
|
@@ -80,12 +80,12 @@ module Pith
|
|
80
80
|
|
81
81
|
def find_input(path)
|
82
82
|
input = project.input(path)
|
83
|
-
@
|
83
|
+
@dependencies << input.file if input
|
84
84
|
input
|
85
85
|
end
|
86
86
|
|
87
87
|
def with_input(input)
|
88
|
-
@
|
88
|
+
@dependencies << input.file
|
89
89
|
@input_stack.push(input)
|
90
90
|
begin
|
91
91
|
yield
|
data/lib/pith/render_context.rb~
CHANGED
@@ -11,7 +11,7 @@ module Pith
|
|
11
11
|
def initialize(project)
|
12
12
|
@project = project
|
13
13
|
@input_stack = []
|
14
|
-
@
|
14
|
+
@referenced_inputs = project.config_files.dup
|
15
15
|
self.extend(project.helper_module)
|
16
16
|
end
|
17
17
|
|
@@ -26,7 +26,6 @@ module Pith
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def render(input, locals = {}, &block)
|
29
|
-
@rendered_inputs << input
|
30
29
|
with_input(input) do
|
31
30
|
result = input.render(self, locals, &block)
|
32
31
|
layout_ref = current_input.meta["layout"]
|
@@ -35,7 +34,7 @@ module Pith
|
|
35
34
|
end
|
36
35
|
end
|
37
36
|
|
38
|
-
attr_reader :
|
37
|
+
attr_reader :referenced_inputs
|
39
38
|
|
40
39
|
def include(template_ref, locals = {}, &block)
|
41
40
|
content_block = if block_given?
|
@@ -62,7 +61,7 @@ module Pith
|
|
62
61
|
def link(target_ref, label = nil)
|
63
62
|
target_path = resolve_path(target_ref)
|
64
63
|
label ||= begin
|
65
|
-
|
64
|
+
find_input(target_path).title
|
66
65
|
rescue Pith::ReferenceError
|
67
66
|
"???"
|
68
67
|
end
|
@@ -79,7 +78,14 @@ module Pith
|
|
79
78
|
current_input.resolve_path(ref)
|
80
79
|
end
|
81
80
|
|
81
|
+
def find_input(path)
|
82
|
+
input = project.input(path)
|
83
|
+
@referenced_inputs << input if input
|
84
|
+
input
|
85
|
+
end
|
86
|
+
|
82
87
|
def with_input(input)
|
88
|
+
@referenced_inputs << input
|
83
89
|
@input_stack.push(input)
|
84
90
|
begin
|
85
91
|
yield
|
@@ -89,7 +95,8 @@ module Pith
|
|
89
95
|
end
|
90
96
|
|
91
97
|
def render_ref(template_ref, locals = {}, &block)
|
92
|
-
|
98
|
+
template_path = resolve_path(template_ref)
|
99
|
+
template = find_input(template_path)
|
93
100
|
render(template, locals, &block)
|
94
101
|
end
|
95
102
|
|
data/lib/pith/version.rb
CHANGED
data/lib/pith/version.rb~
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pith
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 6
|
10
|
+
version: 0.0.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Mike Williams
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-09-
|
18
|
+
date: 2010-09-02 00:00:00 +10:00
|
19
19
|
default_executable: pith
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|