pith 0.0.5 → 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.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
|