ace 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/CHANGELOG +3 -0
- data/LICENSE +20 -0
- data/README.textile +18 -0
- data/TODO +1 -0
- data/ace.gemspec +53 -0
- data/ace.pre.gemspec +6 -0
- data/bin/ace +76 -0
- data/bin/ace-gen +32 -0
- data/example/app/posts.rb +20 -0
- data/example/app/tags.rb +28 -0
- data/example/boot.rb +6 -0
- data/example/config.yml +2 -0
- data/example/content/assets/css/style.css +1 -0
- data/example/content/assets/js/application.js +3 -0
- data/example/content/index.html.haml +5 -0
- data/example/content/posts.json.rb +0 -0
- data/example/content/posts/node-js.html +29 -0
- data/example/content/posts/ruby.html +21 -0
- data/example/layouts/base.html.haml +5 -0
- data/example/layouts/post.html.haml +5 -0
- data/example/layouts/tag.html.haml +6 -0
- data/example/lib/initializer.rb +0 -0
- data/example/output/assets/css/style.css +1 -0
- data/example/output/assets/js/application.js +3 -0
- data/example/output/posts/node-js.html +32 -0
- data/example/output/posts/ruby.html +24 -0
- data/example/output/posts/test.html +10 -0
- data/example/output/tags/development.html +11 -0
- data/example/output/tags/javascript.html +10 -0
- data/example/output/tags/node.js.html +10 -0
- data/example/output/tags/ruby.html +10 -0
- data/example/rules.rb +8 -0
- data/example/tasks.rb +0 -0
- data/lib/ace.rb +140 -0
- data/lib/ace/dsl.rb +21 -0
- data/lib/ace/filters.rb +9 -0
- data/lib/ace/filters/haml.rb +19 -0
- data/lib/ace/filters/layout.rb +22 -0
- data/lib/ace/filters/template.rb +25 -0
- data/lib/ace/version.rb +5 -0
- data/project_generator/metadata.yml +3 -0
- data/project_generator/postprocess.rb +9 -0
- data/project_generator/setup.rb +9 -0
- data/simple-templater.scope +6 -0
- metadata +137 -0
data/.gitignore
ADDED
data/CHANGELOG
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Jakub Šťastný aka Botanicus
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
h1. Why you should be interested in ace?
|
2
|
+
|
3
|
+
In Ace, every page is an instance
|
4
|
+
Typically I want to define methods, like @post.excerpt
|
5
|
+
|
6
|
+
There are also *generators* available for easier generating items on the fly.
|
7
|
+
|
8
|
+
Ace has *template inheritance*. I love template inheritance, it's more flexible pattern than layouts.
|
9
|
+
|
10
|
+
Tasks for deployment included.
|
11
|
+
|
12
|
+
h1. The boot process
|
13
|
+
|
14
|
+
# load @boot.rb@ where the
|
15
|
+
# load the rules (controllers / globs mapping)
|
16
|
+
# load & instantiate the items: only the renderables (concrete post)
|
17
|
+
# run the filters, layoutin' ... actually this can be defined in the controller
|
18
|
+
# match the routes, write the files
|
data/ace.gemspec
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env gem build
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "base64"
|
5
|
+
require File.expand_path("../lib/ace/version", __FILE__)
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "ace"
|
9
|
+
s.version = Ace::VERSION
|
10
|
+
s.authors = ["Jakub Šťastný aka Botanicus"]
|
11
|
+
s.homepage = "http://github.com/botanicus/ace"
|
12
|
+
s.summary = "Ace is highly flexible static pages generator with template inheritance."
|
13
|
+
s.description = "" # TODO: long description
|
14
|
+
s.cert_chain = nil
|
15
|
+
s.email = Base64.decode64("c3Rhc3RueUAxMDFpZGVhcy5jeg==\n")
|
16
|
+
s.has_rdoc = true
|
17
|
+
|
18
|
+
# files
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
|
21
|
+
s.executables = Dir["bin/*"].map(&File.method(:basename))
|
22
|
+
s.default_executable = "ace"
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
|
25
|
+
# Ruby version
|
26
|
+
# Current JRuby with --1.9 switch has RUBY_VERSION set to "1.9.2dev"
|
27
|
+
# and RubyGems don't play well with it, so we have to set minimal
|
28
|
+
# Ruby version to 1.9, even if it actually is 1.9.1
|
29
|
+
s.required_ruby_version = ::Gem::Requirement.new("~> 1.9")
|
30
|
+
|
31
|
+
# Dependencies
|
32
|
+
# RubyGems has runtime dependencies (add_dependency) and
|
33
|
+
# development dependencies (add_development_dependency)
|
34
|
+
# Ace isn't a monolithic framework, so you might want
|
35
|
+
# to use just one specific part of it, so it has no sense
|
36
|
+
# to specify dependencies for the whole gem. If you want
|
37
|
+
# to install everything what you need for start with Ace,
|
38
|
+
# just run gem install ace --development
|
39
|
+
|
40
|
+
s.add_dependency "template-inheritance"
|
41
|
+
s.add_development_dependency "simple-templater", ">= 0.0.1.2"
|
42
|
+
|
43
|
+
begin
|
44
|
+
require "changelog"
|
45
|
+
rescue LoadError
|
46
|
+
warn "You have to have changelog gem installed for post install message"
|
47
|
+
else
|
48
|
+
s.post_install_message = CHANGELOG.new.version_changes
|
49
|
+
end
|
50
|
+
|
51
|
+
# RubyForge
|
52
|
+
s.rubyforge_project = "ace"
|
53
|
+
end
|
data/ace.pre.gemspec
ADDED
data/bin/ace
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
if RUBY_VERSION < "1.9.1"
|
5
|
+
abort "Ace requires Ruby 1.9."
|
6
|
+
end
|
7
|
+
|
8
|
+
base = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
|
9
|
+
libdir = File.expand_path(File.join(File.dirname(base), "..", "lib"))
|
10
|
+
|
11
|
+
# because of system installation, there is bin/../lib, but not bin/../lib/ace
|
12
|
+
if File.directory?(File.join(libdir, "ace"))
|
13
|
+
$:.unshift(libdir) unless $:.include?(libdir)
|
14
|
+
end
|
15
|
+
|
16
|
+
require "ace"
|
17
|
+
require "ace/dsl"
|
18
|
+
|
19
|
+
if File.join(Dir.pwd, "boot.rb")
|
20
|
+
require File.join(Dir.pwd, "boot.rb")
|
21
|
+
else
|
22
|
+
abort "No boot.rb!"
|
23
|
+
end
|
24
|
+
|
25
|
+
if File.join(Dir.pwd, "rules.rb")
|
26
|
+
path = File.join(Dir.pwd, "rules.rb")
|
27
|
+
code = File.read(path)
|
28
|
+
rules = Ace::DSL.new
|
29
|
+
begin
|
30
|
+
rules.instance_eval(code)
|
31
|
+
rescue Exception => exception
|
32
|
+
puts "Error in DSL: #{exception.message}"
|
33
|
+
puts exception.backtrace
|
34
|
+
exit 1
|
35
|
+
end
|
36
|
+
else
|
37
|
+
abort "No rules.rb!"
|
38
|
+
end
|
39
|
+
|
40
|
+
rules.rules.each do |klass, files|
|
41
|
+
puts "#{klass} #{files.inspect}"
|
42
|
+
files.each do |file|
|
43
|
+
if File.binread(file).match(/^-{3,5}\s*$/)
|
44
|
+
raw_item = Ace::RawItem.new(file).tap(&:parse)
|
45
|
+
item = klass.create(raw_item.metadata, raw_item.content)
|
46
|
+
else
|
47
|
+
item = klass.create(Hash.new, File.read(file))
|
48
|
+
end
|
49
|
+
item.original_path = file
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
puts
|
54
|
+
|
55
|
+
rules.generators.each do |generator_klass|
|
56
|
+
puts "~ Running #{generator_klass}"
|
57
|
+
generator = generator_klass.new
|
58
|
+
begin
|
59
|
+
if generator.respond_to?(:run)
|
60
|
+
generator.run
|
61
|
+
else
|
62
|
+
abort "Generator #{generator.inspect} doesn't respond to the #run method!"
|
63
|
+
end
|
64
|
+
rescue Exception => exception
|
65
|
+
puts "Error in generator #{generator.inspect}: #{exception.message}"
|
66
|
+
puts exception.backtrace
|
67
|
+
exit 1
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
puts
|
72
|
+
|
73
|
+
Ace::Item.all_instances.each do |item|
|
74
|
+
puts "~ Generating #{item.output_path}"
|
75
|
+
item.save!
|
76
|
+
end
|
data/bin/ace-gen
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
if RUBY_VERSION < "1.9.1"
|
5
|
+
abort "Ace requires Ruby 1.9."
|
6
|
+
end
|
7
|
+
|
8
|
+
base = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
|
9
|
+
libdir = File.expand_path(File.join(File.dirname(base), "..", "lib"))
|
10
|
+
|
11
|
+
# because of system installation, there is bin/../lib, but not bin/../lib/ace
|
12
|
+
if File.directory?(File.join(libdir, "ace"))
|
13
|
+
$:.unshift(libdir) unless $:.include?(libdir)
|
14
|
+
end
|
15
|
+
|
16
|
+
begin
|
17
|
+
require "simple-templater"
|
18
|
+
rescue LoadError
|
19
|
+
abort "You have to install simple-templater first!"
|
20
|
+
end
|
21
|
+
|
22
|
+
begin
|
23
|
+
templater = SimpleTemplater.new(:ace)
|
24
|
+
generator = templater.find(:project)
|
25
|
+
generator.run(ARGV)
|
26
|
+
rescue SimpleTemplater::TargetAlreadyExist => exception
|
27
|
+
abort exception.message
|
28
|
+
rescue Interrupt
|
29
|
+
exit
|
30
|
+
rescue Exception => exception
|
31
|
+
abort "Exception #{exception.inspect} occured during running generator #{generator.inspect}\n#{exception.backtrace.join("\n")}"
|
32
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "nokogiri"
|
4
|
+
require "ace/filters"
|
5
|
+
|
6
|
+
# Inheritted methods:
|
7
|
+
# - content
|
8
|
+
# - metadata
|
9
|
+
# - config
|
10
|
+
class Post < Ace::Item
|
11
|
+
before Ace::LayoutFilter, layout: "post.html"
|
12
|
+
|
13
|
+
def document
|
14
|
+
Nokogiri::HTML(self.content)
|
15
|
+
end
|
16
|
+
|
17
|
+
def excerpt
|
18
|
+
self.document.css("p.excerpt")
|
19
|
+
end
|
20
|
+
end
|
data/example/app/tags.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class Tag < Ace::Item
|
4
|
+
before Ace::LayoutFilter, layout: "tag.html"
|
5
|
+
end
|
6
|
+
|
7
|
+
class TagPagesGenerator
|
8
|
+
def tags
|
9
|
+
Post.instances.inject(Hash.new) do |buffer, post|
|
10
|
+
if tags = post.metadata[:tags]
|
11
|
+
tags.each do |tag|
|
12
|
+
buffer[tag] ||= Array.new
|
13
|
+
buffer[tag] << post
|
14
|
+
end
|
15
|
+
end
|
16
|
+
buffer
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
self.tags.each do |tag_title, items|
|
22
|
+
tag_name = tag_title.downcase.gsub(" ", "-")
|
23
|
+
metadata = {title: tag_title, timestamp: Time.now}
|
24
|
+
tag = Tag.create(metadata, items)
|
25
|
+
tag.output_path = "output/tags/#{tag_name}.html"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/example/boot.rb
ADDED
data/example/config.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
h1 { color: red; }
|
File without changes
|
@@ -0,0 +1,29 @@
|
|
1
|
+
---
|
2
|
+
title: Node.js Asynchronous JavaScript Framework
|
3
|
+
timestamp: 2010-09-16
|
4
|
+
tags: ["Development", "JavaScript", "Node.js"]
|
5
|
+
---
|
6
|
+
|
7
|
+
<p class="excerpt">
|
8
|
+
Node.js is an evented I/O framework for the V8 JavaScript engine. It is intended for writing scalable network programs such as web servers.
|
9
|
+
</p>
|
10
|
+
|
11
|
+
<p>
|
12
|
+
Node.js is similar in purpose to Twisted for Python, Perl Object Environment for Perl, and EventMachine for Ruby. Unlike most JavaScript, it is not executed in a web browser, but it is rather related to server-side JavaScript. Node.js implements some CommonJS specifications[1]. Node.js includes a REPL environment for interactive testing.
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<pre>
|
16
|
+
var sys = require('sys'),
|
17
|
+
http = require('http');
|
18
|
+
|
19
|
+
http.createServer(function (request, response) {
|
20
|
+
response.writeHead(200, {'Content-Type': 'text/plain'});
|
21
|
+
response.end('Hello World\n');
|
22
|
+
}).listen(8000);
|
23
|
+
|
24
|
+
sys.puts('Server running at http://127.0.0.1:8000/');
|
25
|
+
</pre>
|
26
|
+
|
27
|
+
<p>
|
28
|
+
<em>From <a href="http://en.wikipedia.org/wiki/Node.js">Wikipedia.org</em>.
|
29
|
+
</p>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
title: Ruby Programming Language
|
3
|
+
timestamp: 2010-09-14
|
4
|
+
tags: ["Development", "Ruby"]
|
5
|
+
---
|
6
|
+
|
7
|
+
<p class="excerpt">
|
8
|
+
Ruby is a dynamic, reflective, general purpose object-oriented programming language that combines syntax inspired by Perl with Smalltalk-like features. Ruby originated in Japan during the mid-1990s and was first developed and designed by Yukihiro "Matz" Matsumoto. It was influenced primarily by Perl, Smalltalk, Eiffel, and Lisp.
|
9
|
+
</p>
|
10
|
+
|
11
|
+
<p>
|
12
|
+
Ruby supports multiple programming paradigms, including functional, object oriented, imperative and reflective. It also has a dynamic type system and automatic memory management; it is therefore similar in varying respects to Python, Perl, Lisp, Dylan, Pike, and CLU.
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<p>
|
16
|
+
The standard 1.8.7 implementation is written in C, as a single-pass interpreted language. There is currently no specification of the Ruby language, so the original implementation is considered to be the de facto reference. As of 2010[update], there are a number of complete or upcoming alternative implementations of the Ruby language, including YARV, JRuby, Rubinius, IronRuby, MacRuby, and HotRuby, each of which takes a different approach, with IronRuby, JRuby and MacRuby providing just-in-time compilation and MacRuby also providing ahead-of-time compilation. The official 1.9 branch uses YARV, as will 2.0 (development), and will eventually supersede the slower Ruby MRI.
|
17
|
+
</p>
|
18
|
+
|
19
|
+
<p>
|
20
|
+
<em>From <a href="http://en.wikipedia.org/wiki/Ruby_%28programming_language%29">Wikipedia.org</em>.
|
21
|
+
</p>
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
h1 { color: red; }
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html>
|
3
|
+
<head></head>
|
4
|
+
<body>
|
5
|
+
<div id='main'>
|
6
|
+
<h1>My Coooooool Bloogiiiiseeeeek!</h1>
|
7
|
+
<p class="excerpt">
|
8
|
+
Node.js is an evented I/O framework for the V8 JavaScript engine. It is intended for writing scalable network programs such as web servers.
|
9
|
+
</p>
|
10
|
+
|
11
|
+
<p>
|
12
|
+
Node.js is similar in purpose to Twisted for Python, Perl Object Environment for Perl, and EventMachine for Ruby. Unlike most JavaScript, it is not executed in a web browser, but it is rather related to server-side JavaScript. Node.js implements some CommonJS specifications[1]. Node.js includes a REPL environment for interactive testing.
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<pre>
|
16
|
+
var sys = require('sys'),
|
17
|
+
http = require('http');
|
18
|
+
|
19
|
+
http.createServer(function (request, response) {
|
20
|
+
response.writeHead(200, {'Content-Type': 'text/plain'});
|
21
|
+
response.end('Hello World\n');
|
22
|
+
}).listen(8000);
|
23
|
+
|
24
|
+
sys.puts('Server running at http://127.0.0.1:8000/');
|
25
|
+
</pre>
|
26
|
+
|
27
|
+
<p>
|
28
|
+
<em>From <a href="http://en.wikipedia.org/wiki/Node.js">Wikipedia.org</em>.
|
29
|
+
</p>
|
30
|
+
</div>
|
31
|
+
</body>
|
32
|
+
</html>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html>
|
3
|
+
<head></head>
|
4
|
+
<body>
|
5
|
+
<div id='main'>
|
6
|
+
<h1>My Coooooool Bloogiiiiseeeeek!</h1>
|
7
|
+
<p class="excerpt">
|
8
|
+
Ruby is a dynamic, reflective, general purpose object-oriented programming language that combines syntax inspired by Perl with Smalltalk-like features. Ruby originated in Japan during the mid-1990s and was first developed and designed by Yukihiro "Matz" Matsumoto. It was influenced primarily by Perl, Smalltalk, Eiffel, and Lisp.
|
9
|
+
</p>
|
10
|
+
|
11
|
+
<p>
|
12
|
+
Ruby supports multiple programming paradigms, including functional, object oriented, imperative and reflective. It also has a dynamic type system and automatic memory management; it is therefore similar in varying respects to Python, Perl, Lisp, Dylan, Pike, and CLU.
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<p>
|
16
|
+
The standard 1.8.7 implementation is written in C, as a single-pass interpreted language. There is currently no specification of the Ruby language, so the original implementation is considered to be the de facto reference. As of 2010[update], there are a number of complete or upcoming alternative implementations of the Ruby language, including YARV, JRuby, Rubinius, IronRuby, MacRuby, and HotRuby, each of which takes a different approach, with IronRuby, JRuby and MacRuby providing just-in-time compilation and MacRuby also providing ahead-of-time compilation. The official 1.9 branch uses YARV, as will 2.0 (development), and will eventually supersede the slower Ruby MRI.
|
17
|
+
</p>
|
18
|
+
|
19
|
+
<p>
|
20
|
+
<em>From <a href="http://en.wikipedia.org/wiki/Ruby_%28programming_language%29">Wikipedia.org</em>.
|
21
|
+
</p>
|
22
|
+
</div>
|
23
|
+
</body>
|
24
|
+
</html>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html>
|
3
|
+
<head></head>
|
4
|
+
<body>
|
5
|
+
<div id='main'>
|
6
|
+
<h1>My Coooooool Bloogiiiiseeeeek!</h1>
|
7
|
+
Node.js Asynchronous JavaScript Framework
|
8
|
+
Ruby Programming Language
|
9
|
+
</div>
|
10
|
+
</body>
|
11
|
+
</html>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html>
|
3
|
+
<head></head>
|
4
|
+
<body>
|
5
|
+
<div id='main'>
|
6
|
+
<h1>My Coooooool Bloogiiiiseeeeek!</h1>
|
7
|
+
Node.js Asynchronous JavaScript Framework
|
8
|
+
</div>
|
9
|
+
</body>
|
10
|
+
</html>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html>
|
3
|
+
<head></head>
|
4
|
+
<body>
|
5
|
+
<div id='main'>
|
6
|
+
<h1>My Coooooool Bloogiiiiseeeeek!</h1>
|
7
|
+
Node.js Asynchronous JavaScript Framework
|
8
|
+
</div>
|
9
|
+
</body>
|
10
|
+
</html>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html>
|
3
|
+
<head></head>
|
4
|
+
<body>
|
5
|
+
<div id='main'>
|
6
|
+
<h1>My Coooooool Bloogiiiiseeeeek!</h1>
|
7
|
+
Ruby Programming Language
|
8
|
+
</div>
|
9
|
+
</body>
|
10
|
+
</html>
|
data/example/rules.rb
ADDED
data/example/tasks.rb
ADDED
File without changes
|
data/lib/ace.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# === The boot process === #
|
4
|
+
# 1) load the app
|
5
|
+
# 2) load the rules (controllers / globs mapping)
|
6
|
+
# 3) load & instantiate all the renderable items
|
7
|
+
# 4) render all the items (here the filters & layouting run)
|
8
|
+
# 5) match the routes, write the files
|
9
|
+
|
10
|
+
require "yaml"
|
11
|
+
require "fileutils"
|
12
|
+
|
13
|
+
module Ace
|
14
|
+
class RawItem
|
15
|
+
attr_accessor :path, :metadata, :content
|
16
|
+
def initialize(path)
|
17
|
+
@data = File.read(path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def parse
|
21
|
+
pieces = @data.split(/^-{3,5}\s*$/)
|
22
|
+
if pieces.size < 3
|
23
|
+
raise RuntimeError.new(
|
24
|
+
"The file '#{content_filename}' appears to start with a metadata section (three or five dashes at the top) but it does not seem to be in the correct format."
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Parse
|
29
|
+
self.metadata = YAML.load(pieces[1]).inject(Hash.new) { |metadata, pair| metadata.merge(pair[0].to_sym => pair[1]) } || Hash.new
|
30
|
+
self.content = pieces[2..-1].join.strip
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# This class represents the items which will be
|
35
|
+
# eventually rendered like concrete posts, tags etc.
|
36
|
+
class Item
|
37
|
+
def self.inherited(subclass)
|
38
|
+
self.subclasses << subclass
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.subclasses
|
42
|
+
@subclasses ||= Array.new
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.instances
|
46
|
+
@instances ||= Array.new
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.all_subclasses
|
50
|
+
self.subclasses + self.subclasses.map(&:subclasses).flatten
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.all_instances
|
54
|
+
self.all_subclasses.map(&:instances).flatten
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.before_filters
|
58
|
+
@before_filters ||= Array.new
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.before(filter, *args)
|
62
|
+
self.before_filters << filter.new(*args)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.after_filters
|
66
|
+
@after_filters ||= Array.new
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.after(filter, *args)
|
70
|
+
self.after_filters << filter.new(*args)
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.create(metadata, content)
|
74
|
+
self.new(metadata, content).tap(&:register)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Content can be anything, not just a string.
|
78
|
+
attr_accessor :metadata, :content
|
79
|
+
attr_accessor :original_path
|
80
|
+
def initialize(metadata, content)
|
81
|
+
@metadata = metadata
|
82
|
+
@content = content
|
83
|
+
end
|
84
|
+
|
85
|
+
def config
|
86
|
+
@config ||= begin
|
87
|
+
YAML::load_file("config.yml").inject(Hash.new) do |hash, pair|
|
88
|
+
hash.merge!(pair[0].to_sym => pair[1])
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def register
|
94
|
+
instances = self.class.instances
|
95
|
+
unless instances.include?(self)
|
96
|
+
self.class.instances << self
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def unregister
|
101
|
+
self.class.instances.delete(self)
|
102
|
+
end
|
103
|
+
|
104
|
+
def render
|
105
|
+
output = self.class.before_filters.inject(self.content) do |buffer, filter|
|
106
|
+
filter.call(self, buffer)
|
107
|
+
end
|
108
|
+
|
109
|
+
self.class.after_filters.inject(output) do |buffer, filter|
|
110
|
+
filter.call(self, buffer)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
attr_writer :output_path
|
115
|
+
def output_path
|
116
|
+
@output_path ||= begin
|
117
|
+
unless self.original_path.nil?
|
118
|
+
self.original_path.sub("content", "output")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def save!
|
124
|
+
content = self.render # so filters can influence output_path
|
125
|
+
|
126
|
+
FileUtils.mkdir_p File.dirname(self.output_path)
|
127
|
+
File.open(self.output_path, "w") do |file|
|
128
|
+
file.puts(content)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class Asset < Item
|
134
|
+
end
|
135
|
+
|
136
|
+
module Helpers
|
137
|
+
def link_to(anchor, path_or_item, options = nil)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
data/lib/ace/dsl.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Ace
|
4
|
+
class DSL
|
5
|
+
attr_accessor :rules, :generators
|
6
|
+
def initialize
|
7
|
+
@rules, @generators = Hash.new, Array.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def rule(klass, *globs)
|
11
|
+
paths = globs.map { |glob| Dir.glob("content/#{glob}") }
|
12
|
+
files = paths.flatten.select { |path| File.file?(path) }
|
13
|
+
self.rules[klass] ||= Array.new
|
14
|
+
self.rules[klass].push(*files)
|
15
|
+
end
|
16
|
+
|
17
|
+
def generator(klass)
|
18
|
+
self.generators << klass
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/ace/filters.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "haml"
|
4
|
+
require "ace/filters"
|
5
|
+
|
6
|
+
# This is just a plain Haml, no template inheritance.
|
7
|
+
module Ace
|
8
|
+
class HamlFilter < Filter
|
9
|
+
# http://haml.hamptoncatlin.com/docs/rdoc/classes/Haml/Engine.html
|
10
|
+
def call(item, content)
|
11
|
+
if item.output_path && item.output_path.end_with?(".haml")
|
12
|
+
item.output_path.sub!(/\.haml$/, "")
|
13
|
+
end
|
14
|
+
|
15
|
+
engine = Haml::Engine.new(content)
|
16
|
+
engine.render(item.extend(Ace::Helpers))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "ace/filters"
|
4
|
+
require "template-inheritance"
|
5
|
+
|
6
|
+
layouts = File.join(Dir.pwd, "layouts")
|
7
|
+
unless TemplateInheritance::Template.paths.include?(layouts)
|
8
|
+
TemplateInheritance::Template.paths.unshift(layouts)
|
9
|
+
end
|
10
|
+
|
11
|
+
module Ace
|
12
|
+
class LayoutFilter < Filter
|
13
|
+
def initialize(options)
|
14
|
+
@path = options[:layout]
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(item, content)
|
18
|
+
template = TemplateInheritance::Template.new(@path)
|
19
|
+
return template.render(item: item)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "ace/filters"
|
4
|
+
require "template-inheritance"
|
5
|
+
|
6
|
+
layouts = File.join(Dir.pwd, "layouts")
|
7
|
+
unless TemplateInheritance::Template.paths.include?(layouts)
|
8
|
+
TemplateInheritance::Template.paths.unshift(layouts)
|
9
|
+
end
|
10
|
+
|
11
|
+
TemplateInheritance::Template.paths << File.join(Dir.pwd, "content")
|
12
|
+
|
13
|
+
module Ace
|
14
|
+
class TemplateFilter < Filter
|
15
|
+
def call(item, content)
|
16
|
+
if item.output_path
|
17
|
+
item.output_path = item.output_path.split(".")[0..-2].join(".")
|
18
|
+
end
|
19
|
+
|
20
|
+
relative_path = item.original_path.sub("content/", "")
|
21
|
+
template = TemplateInheritance::Template.new(relative_path)
|
22
|
+
return template.render(item: item)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/ace/version.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# This hook will be executed after templater finish in context of current generator object.
|
4
|
+
# Current directory is what you just generated, unless this is flat generator.
|
5
|
+
|
6
|
+
unless RUBY_PLATFORM.match(/mswin|mingw/)
|
7
|
+
sh "chmod +x boot.rb"
|
8
|
+
sh "chmod +x tasks.rb"
|
9
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# This hook will be executed in context of current generator object before templater start to generate new files.
|
4
|
+
# You can update context hash and register hooks. Don't forget to use merge! instead of merge, because you are
|
5
|
+
# manipulating with one object, rather than returning new one.
|
6
|
+
|
7
|
+
hook do |generator, context|
|
8
|
+
# TODO
|
9
|
+
end
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ace
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
version: "0.1"
|
9
|
+
platform: ruby
|
10
|
+
authors:
|
11
|
+
- "Jakub \xC5\xA0\xC5\xA5astn\xC3\xBD aka Botanicus"
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
14
|
+
cert_chain:
|
15
|
+
date: 2011-02-17 00:00:00 +00:00
|
16
|
+
default_executable: ace
|
17
|
+
dependencies:
|
18
|
+
- !ruby/object:Gem::Dependency
|
19
|
+
name: template-inheritance
|
20
|
+
prerelease: false
|
21
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
22
|
+
none: false
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
segments:
|
27
|
+
- 0
|
28
|
+
version: "0"
|
29
|
+
type: :runtime
|
30
|
+
version_requirements: *id001
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: simple-templater
|
33
|
+
prerelease: false
|
34
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 0
|
41
|
+
- 0
|
42
|
+
- 1
|
43
|
+
- 2
|
44
|
+
version: 0.0.1.2
|
45
|
+
type: :development
|
46
|
+
version_requirements: *id002
|
47
|
+
description: ""
|
48
|
+
email: stastny@101ideas.cz
|
49
|
+
executables:
|
50
|
+
- ace
|
51
|
+
- ace-gen
|
52
|
+
extensions: []
|
53
|
+
|
54
|
+
extra_rdoc_files: []
|
55
|
+
|
56
|
+
files:
|
57
|
+
- .gitignore
|
58
|
+
- CHANGELOG
|
59
|
+
- LICENSE
|
60
|
+
- README.textile
|
61
|
+
- TODO
|
62
|
+
- ace.gemspec
|
63
|
+
- ace.pre.gemspec
|
64
|
+
- bin/ace
|
65
|
+
- bin/ace-gen
|
66
|
+
- example/app/posts.rb
|
67
|
+
- example/app/tags.rb
|
68
|
+
- example/boot.rb
|
69
|
+
- example/config.yml
|
70
|
+
- example/content/assets/css/style.css
|
71
|
+
- example/content/assets/js/application.js
|
72
|
+
- example/content/index.html.haml
|
73
|
+
- example/content/posts.json.rb
|
74
|
+
- example/content/posts/node-js.html
|
75
|
+
- example/content/posts/ruby.html
|
76
|
+
- example/layouts/base.html.haml
|
77
|
+
- example/layouts/post.html.haml
|
78
|
+
- example/layouts/tag.html.haml
|
79
|
+
- example/lib/initializer.rb
|
80
|
+
- example/output/assets/css/style.css
|
81
|
+
- example/output/assets/js/application.js
|
82
|
+
- example/output/posts/node-js.html
|
83
|
+
- example/output/posts/ruby.html
|
84
|
+
- example/output/posts/test.html
|
85
|
+
- example/output/tags/development.html
|
86
|
+
- example/output/tags/javascript.html
|
87
|
+
- example/output/tags/node.js.html
|
88
|
+
- example/output/tags/ruby.html
|
89
|
+
- example/rules.rb
|
90
|
+
- example/tasks.rb
|
91
|
+
- lib/ace.rb
|
92
|
+
- lib/ace/dsl.rb
|
93
|
+
- lib/ace/filters.rb
|
94
|
+
- lib/ace/filters/haml.rb
|
95
|
+
- lib/ace/filters/layout.rb
|
96
|
+
- lib/ace/filters/template.rb
|
97
|
+
- lib/ace/version.rb
|
98
|
+
- project_generator/metadata.yml
|
99
|
+
- project_generator/postprocess.rb
|
100
|
+
- project_generator/setup.rb
|
101
|
+
- simple-templater.scope
|
102
|
+
has_rdoc: true
|
103
|
+
homepage: http://github.com/botanicus/ace
|
104
|
+
licenses: []
|
105
|
+
|
106
|
+
post_install_message: "[\e[32mVersion 0.0.1\e[0m] Items\n\
|
107
|
+
[\e[32mVersion 0.0.1\e[0m] Generators\n"
|
108
|
+
rdoc_options: []
|
109
|
+
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
segments:
|
118
|
+
- 1
|
119
|
+
- 9
|
120
|
+
version: "1.9"
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
segments:
|
127
|
+
- 0
|
128
|
+
version: "0"
|
129
|
+
requirements: []
|
130
|
+
|
131
|
+
rubyforge_project: ace
|
132
|
+
rubygems_version: 1.3.7
|
133
|
+
signing_key:
|
134
|
+
specification_version: 3
|
135
|
+
summary: Ace is highly flexible static pages generator with template inheritance.
|
136
|
+
test_files: []
|
137
|
+
|