pith 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,28 +1,21 @@
1
1
  Pith
2
2
  ====
3
3
 
4
- Pith is a static web-site generator, written in Ruby.
4
+ Pith is a static website generator, written in Ruby.
5
5
 
6
6
  Using Pith, you can:
7
7
 
8
- * __Express yourself succintly__ using Markdown or Textile.
8
+ * Lay-out your page designs in [Haml][haml], ERb, or Liquid.
9
9
 
10
- * __Layout your pages__ written in ERb, [Haml][haml], or Liquid.
10
+ * Style things up using [Sass][sass].
11
11
 
12
- * __Style things up using__ [Sass][sass].
12
+ * Succintly add content using Markdown or Textile.
13
13
 
14
- * __Encapsulate common markup__ in "layout" and "partial" templates.
14
+ * Encapsulate common markup in "layout" and "partial" templates.
15
15
 
16
- * __Easily link pages and resources__ using relative links.
16
+ * Easily link pages (and resources) using relative links.
17
17
 
18
- * __Quickly test changes__ using the built-in web-server.
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
@@ -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
@@ -28,7 +28,7 @@ module Pith
28
28
  # Return true unless output needs to be re-generated.
29
29
  #
30
30
  def uptodate?
31
- all_input_files && FileUtils.uptodate?(output_file, all_input_files)
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
- remember_dependencies(render_context.referenced_inputs)
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
- def remember_dependencies(referenced_inputs)
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
 
@@ -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.rendered_inputs)
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(rendered_inputs)
116
- @all_input_files = rendered_inputs.map { |input| input.file }
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
@@ -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)
@@ -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)
@@ -11,7 +11,7 @@ module Pith
11
11
  def initialize(project)
12
12
  @project = project
13
13
  @input_stack = []
14
- @referenced_inputs = Set.new
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 :referenced_inputs
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
- @referenced_inputs << input if input
83
+ @dependencies << input.file if input
84
84
  input
85
85
  end
86
86
 
87
87
  def with_input(input)
88
- @referenced_inputs << input
88
+ @dependencies << input.file
89
89
  @input_stack.push(input)
90
90
  begin
91
91
  yield
@@ -11,7 +11,7 @@ module Pith
11
11
  def initialize(project)
12
12
  @project = project
13
13
  @input_stack = []
14
- @rendered_inputs = Set.new
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 :rendered_inputs
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
- project.input(target_path).title
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
- template = project.input(resolve_path(template_ref))
98
+ template_path = resolve_path(template_ref)
99
+ template = find_input(template_path)
93
100
  render(template, locals, &block)
94
101
  end
95
102
 
@@ -1,3 +1,3 @@
1
1
  module Pith
2
- VERSION = "0.0.5".freeze
2
+ VERSION = "0.0.6".freeze
3
3
  end
@@ -1,3 +1,3 @@
1
1
  module Pith
2
- VERSION = "0.0.4".freeze
2
+ VERSION = "0.0.5".freeze
3
3
  end
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: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 5
10
- version: 0.0.5
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-01 00:00:00 +10:00
18
+ date: 2010-09-02 00:00:00 +10:00
19
19
  default_executable: pith
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency