Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial import

  • Loading branch information...
commit 4cc4e303abf87ee2f4b601a5c6fb2eb5bd8b8650 0 parents
Jakub Šťastný aka Botanicus authored
Showing with 691 additions and 0 deletions.
  1. +3 −0  .gitignore
  2. +3 −0  CHANGELOG
  3. +20 −0 LICENSE
  4. +18 −0 README.textile
  5. +1 −0  TODO
  6. +53 −0 ace.gemspec
  7. +6 −0 ace.pre.gemspec
  8. +76 −0 bin/ace
  9. +32 −0 bin/ace-gen
  10. +20 −0 example/app/posts.rb
  11. +28 −0 example/app/tags.rb
  12. +6 −0 example/boot.rb
  13. +2 −0  example/config.yml
  14. +1 −0  example/content/assets/css/style.css
  15. +3 −0  example/content/assets/js/application.js
  16. +5 −0 example/content/index.html.haml
  17. 0  example/content/posts.json.rb
  18. +29 −0 example/content/posts/node-js.html
  19. +21 −0 example/content/posts/ruby.html
  20. +5 −0 example/layouts/base.html.haml
  21. +5 −0 example/layouts/post.html.haml
  22. +6 −0 example/layouts/tag.html.haml
  23. 0  example/lib/initializer.rb
  24. +1 −0  example/output/assets/css/style.css
  25. +3 −0  example/output/assets/js/application.js
  26. +32 −0 example/output/posts/node-js.html
  27. +24 −0 example/output/posts/ruby.html
  28. +10 −0 example/output/posts/test.html
  29. +11 −0 example/output/tags/development.html
  30. +10 −0 example/output/tags/javascript.html
  31. +10 −0 example/output/tags/node.js.html
  32. +10 −0 example/output/tags/ruby.html
  33. +8 −0 example/rules.rb
  34. 0  example/tasks.rb
  35. +130 −0 lib/ace.rb
  36. +21 −0 lib/ace/dsl.rb
  37. +9 −0 lib/ace/filters.rb
  38. +18 −0 lib/ace/filters/haml.rb
  39. +19 −0 lib/ace/filters/layout.rb
  40. +5 −0 lib/ace/version.rb
  41. +3 −0  project_generator/metadata.yml
  42. +9 −0 project_generator/postprocess.rb
  43. +9 −0 project_generator/setup.rb
  44. +6 −0 simple-templater.scope
3  .gitignore
@@ -0,0 +1,3 @@
+/*.gem
+.DS_Store
+.rvmrc
3  CHANGELOG
@@ -0,0 +1,3 @@
+= Version 0.0.1
+ * Items
+ * Generators
20 LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2010 Jakub Šťastný aka Botanicus
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 README.textile
@@ -0,0 +1,18 @@
+h1. Why you should be interested in ace?
+
+In Ace, every page is an instance
+Typically I want to define methods, like @post.excerpt
+
+There are also *generators* available for easier generating items on the fly.
+
+Ace has *template inheritance*. I love template inheritance, it's more flexible pattern than layouts.
+
+Tasks for deployment included.
+
+h1. The boot process
+
+# load @boot.rb@ where the
+# load the rules (controllers / globs mapping)
+# load & instantiate the items: only the renderables (concrete post)
+# run the filters, layoutin' ... actually this can be defined in the controller
+# match the routes, write the files
1  TODO
@@ -0,0 +1 @@
+- ace-gen myproject
53 ace.gemspec
@@ -0,0 +1,53 @@
+#!/usr/bin/env gem build
+# encoding: utf-8
+
+require "base64"
+require File.expand_path("../lib/ace/version", __FILE__)
+
+Gem::Specification.new do |s|
+ s.name = "ace"
+ s.version = Ace::VERSION
+ s.authors = ["Jakub Šťastný aka Botanicus"]
+ s.homepage = "http://github.com/botanicus/ace"
+ s.summary = "Ace is highly flexible static pages generator with template inheritance."
+ s.description = "" # TODO: long description
+ s.cert_chain = nil
+ s.email = Base64.decode64("c3Rhc3RueUAxMDFpZGVhcy5jeg==\n")
+ s.has_rdoc = true
+
+ # files
+ s.files = `git ls-files`.split("\n")
+
+ s.executables = Dir["bin/*"].map(&File.method(:basename))
+ s.default_executable = "ace"
+ s.require_paths = ["lib"]
+
+ # Ruby version
+ # Current JRuby with --1.9 switch has RUBY_VERSION set to "1.9.2dev"
+ # and RubyGems don't play well with it, so we have to set minimal
+ # Ruby version to 1.9, even if it actually is 1.9.1
+ s.required_ruby_version = ::Gem::Requirement.new("~> 1.9")
+
+ # Dependencies
+ # RubyGems has runtime dependencies (add_dependency) and
+ # development dependencies (add_development_dependency)
+ # Ace isn't a monolithic framework, so you might want
+ # to use just one specific part of it, so it has no sense
+ # to specify dependencies for the whole gem. If you want
+ # to install everything what you need for start with Ace,
+ # just run gem install ace --development
+
+ s.add_dependency "template-inheritance"
+ s.add_development_dependency "simple-templater", ">= 0.0.1.2"
+
+ begin
+ require "changelog"
+ rescue LoadError
+ warn "You have to have changelog gem installed for post install message"
+ else
+ s.post_install_message = CHANGELOG.new.version_changes
+ end
+
+ # RubyForge
+ s.rubyforge_project = "ace"
+end
6 ace.pre.gemspec
@@ -0,0 +1,6 @@
+#!/usr/bin/env gem build
+# encoding: utf-8
+
+eval(File.read("ace.gemspec")).tap do |specification|
+ specification.version = "#{specification.version}.pre"
+end
76 bin/ace
@@ -0,0 +1,76 @@
+#!/usr/bin/env ruby
+# encoding: utf-8
+
+if RUBY_VERSION < "1.9.1"
+ abort "Ace requires Ruby 1.9."
+end
+
+base = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
+libdir = File.expand_path(File.join(File.dirname(base), "..", "lib"))
+
+# because of system installation, there is bin/../lib, but not bin/../lib/ace
+if File.directory?(File.join(libdir, "ace"))
+ $:.unshift(libdir) unless $:.include?(libdir)
+end
+
+require "ace"
+require "ace/dsl"
+
+if File.join(Dir.pwd, "boot.rb")
+ require File.join(Dir.pwd, "boot.rb")
+else
+ abort "No boot.rb!"
+end
+
+if File.join(Dir.pwd, "rules.rb")
+ path = File.join(Dir.pwd, "rules.rb")
+ code = File.read(path)
+ rules = Ace::DSL.new
+ begin
+ rules.instance_eval(code)
+ rescue Exception => exception
+ puts "Error in DSL: #{exception.message}"
+ puts exception.backtrace
+ exit 1
+ end
+else
+ abort "No rules.rb!"
+end
+
+rules.rules.each do |klass, files|
+ puts "#{klass} #{files.inspect}"
+ files.each do |file|
+ if File.binread(file).match(/^-{3,5}\s*$/)
+ raw_item = Ace::RawItem.new(file).tap(&:parse)
+ item = klass.create(raw_item.metadata, raw_item.content)
+ else
+ item = klass.create(Hash.new, File.read(file))
+ end
+ item.original_path = file
+ end
+end
+
+puts
+
+rules.generators.each do |generator_klass|
+ puts "Running #{generator_klass}"
+ generator = generator_klass.new
+ begin
+ if generator.respond_to?(:run)
+ generator.run
+ else
+ abort "Generator #{generator.inspect} doesn't respond to the #run method!"
+ end
+ rescue Exception => exception
+ puts "Error in generator #{generator.inspect}: #{exception.message}"
+ puts exception.backtrace
+ exit 1
+ end
+end
+
+puts
+
+Ace::Item.instances.each do |item|
+ puts "Generating #{item.output_path}"
+ item.save!
+end
32 bin/ace-gen
@@ -0,0 +1,32 @@
+#!/usr/bin/env ruby
+# encoding: utf-8
+
+if RUBY_VERSION < "1.9.1"
+ abort "Ace requires Ruby 1.9."
+end
+
+base = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
+libdir = File.expand_path(File.join(File.dirname(base), "..", "lib"))
+
+# because of system installation, there is bin/../lib, but not bin/../lib/ace
+if File.directory?(File.join(libdir, "ace"))
+ $:.unshift(libdir) unless $:.include?(libdir)
+end
+
+begin
+ require "simple-templater"
+rescue LoadError
+ abort "You have to install simple-templater first!"
+end
+
+begin
+ templater = SimpleTemplater.new(:ace)
+ generator = templater.find(:project)
+ generator.run(ARGV)
+rescue SimpleTemplater::TargetAlreadyExist => exception
+ abort exception.message
+rescue Interrupt
+ exit
+rescue Exception => exception
+ abort "Exception #{exception.inspect} occured during running generator #{generator.inspect}\n#{exception.backtrace.join("\n")}"
+end
20 example/app/posts.rb
@@ -0,0 +1,20 @@
+# encoding: utf-8
+
+require "nokogiri"
+require "ace/filters"
+
+# Inheritted methods:
+# - content
+# - metadata
+# - config
+class Post < Ace::Item
+ before Ace::LayoutFilter, layout: "post.html"
+
+ def document
+ Nokogiri::HTML(self.content)
+ end
+
+ def excerpt
+ self.document.css("p.excerpt")
+ end
+end
28 example/app/tags.rb
@@ -0,0 +1,28 @@
+# encoding: utf-8
+
+class Tag < Ace::Item
+ before Ace::LayoutFilter, layout: "tag.html"
+end
+
+class TagPagesGenerator
+ def tags
+ Post.instances.inject(Hash.new) do |buffer, post|
+ if tags = post.metadata[:tags]
+ tags.each do |tag|
+ buffer[tag] ||= Array.new
+ buffer[tag] << post
+ end
+ end
+ buffer
+ end
+ end
+
+ def run
+ self.tags.each do |tag_title, items|
+ tag_name = tag_title.downcase.gsub(" ", "-")
+ metadata = {title: tag_title, timestamp: Time.now}
+ tag = Tag.create(metadata, items)
+ tag.output_path = "output/tags/#{tag_name}.html"
+ end
+ end
+end
6 example/boot.rb
@@ -0,0 +1,6 @@
+#!/usr/bin/env ace
+# encoding: utf-8
+
+Dir["app/**/*.rb"].each do |file|
+ load file
+end
2  example/config.yml
@@ -0,0 +1,2 @@
+title: ""
+base_url: ""
1  example/content/assets/css/style.css
@@ -0,0 +1 @@
+h1 { color: red; }
3  example/content/assets/js/application.js
@@ -0,0 +1,3 @@
+window.onload = function () {
+ console.log("I don't do nothing really, I'm just pretending to be a useful asset.");
+};
5 example/content/index.html.haml
@@ -0,0 +1,5 @@
+- extends "base.html"
+
+- Post.each do |post|
+ %h2= post.title
+ = post.excerpt
0  example/content/posts.json.rb
No changes.
29 example/content/posts/node-js.html
@@ -0,0 +1,29 @@
+---
+title: Node.js Asynchronous JavaScript Framework
+timestamp: 2010-09-16
+tags: ["Development", "JavaScript", "Node.js"]
+---
+
+<p class="excerpt">
+ 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.
+</p>
+
+<p>
+ 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.
+</p>
+
+<pre>
+var sys = require('sys'),
+ http = require('http');
+
+http.createServer(function (request, response) {
+ response.writeHead(200, {'Content-Type': 'text/plain'});
+ response.end('Hello World\n');
+}).listen(8000);
+
+sys.puts('Server running at http://127.0.0.1:8000/');
+</pre>
+
+<p>
+ <em>From <a href="http://en.wikipedia.org/wiki/Node.js">Wikipedia.org</em>.
+</p>
21 example/content/posts/ruby.html
@@ -0,0 +1,21 @@
+---
+title: Ruby Programming Language
+timestamp: 2010-09-14
+tags: ["Development", "Ruby"]
+---
+
+<p class="excerpt">
+ 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.
+</p>
+
+<p>
+ 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.
+</p>
+
+<p>
+ 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.
+</p>
+
+<p>
+ <em>From <a href="http://en.wikipedia.org/wiki/Ruby_%28programming_language%29">Wikipedia.org</em>.
+</p>
5 example/layouts/base.html.haml
@@ -0,0 +1,5 @@
+!!!
+%html
+ %head
+ %body
+ #main= block(:body)
5 example/layouts/post.html.haml
@@ -0,0 +1,5 @@
+- extends "base.html"
+
+- block(:body) do
+ %h1 My Coooooool Bloogiiiiseeeeek!
+ = item.content
6 example/layouts/tag.html.haml
@@ -0,0 +1,6 @@
+- extends "base.html"
+
+- block(:body) do
+ %h1 My Coooooool Bloogiiiiseeeeek!
+ - item.content.each do |post|
+ = post.metadata[:title]
0  example/lib/initializer.rb
No changes.
1  example/output/assets/css/style.css
@@ -0,0 +1 @@
+h1 { color: red; }
3  example/output/assets/js/application.js
@@ -0,0 +1,3 @@
+window.onload = function () {
+ console.log("I don't do nothing really, I'm just pretending to be a useful asset.");
+};
32 example/output/posts/node-js.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+ <head></head>
+ <body>
+ <div id='main'>
+ <h1>My Coooooool Bloogiiiiseeeeek!</h1>
+ <p class="excerpt">
+ 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.
+ </p>
+
+ <p>
+ 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.
+ </p>
+
+ <pre>
+ var sys = require('sys'),
+ http = require('http');
+
+ http.createServer(function (request, response) {
+ response.writeHead(200, {'Content-Type': 'text/plain'});
+ response.end('Hello World\n');
+ }).listen(8000);
+
+ sys.puts('Server running at http://127.0.0.1:8000/');
+ </pre>
+
+ <p>
+ <em>From <a href="http://en.wikipedia.org/wiki/Node.js">Wikipedia.org</em>.
+ </p>
+ </div>
+ </body>
+</html>
24 example/output/posts/ruby.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+ <head></head>
+ <body>
+ <div id='main'>
+ <h1>My Coooooool Bloogiiiiseeeeek!</h1>
+ <p class="excerpt">
+ 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.
+ </p>
+
+ <p>
+ 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.
+ </p>
+
+ <p>
+ 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.
+ </p>
+
+ <p>
+ <em>From <a href="http://en.wikipedia.org/wiki/Ruby_%28programming_language%29">Wikipedia.org</em>.
+ </p>
+ </div>
+ </body>
+</html>
10 example/output/posts/test.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+ <head></head>
+ <body>
+ <div id='main'>
+ <h1>My Coooooool Bloogiiiiseeeeek!</h1>
+ content
+ </div>
+ </body>
+</html>
11 example/output/tags/development.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+ <head></head>
+ <body>
+ <div id='main'>
+ <h1>My Coooooool Bloogiiiiseeeeek!</h1>
+ Node.js Asynchronous JavaScript Framework
+ Ruby Programming Language
+ </div>
+ </body>
+</html>
10 example/output/tags/javascript.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+ <head></head>
+ <body>
+ <div id='main'>
+ <h1>My Coooooool Bloogiiiiseeeeek!</h1>
+ Node.js Asynchronous JavaScript Framework
+ </div>
+ </body>
+</html>
10 example/output/tags/node.js.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+ <head></head>
+ <body>
+ <div id='main'>
+ <h1>My Coooooool Bloogiiiiseeeeek!</h1>
+ Node.js Asynchronous JavaScript Framework
+ </div>
+ </body>
+</html>
10 example/output/tags/ruby.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+ <head></head>
+ <body>
+ <div id='main'>
+ <h1>My Coooooool Bloogiiiiseeeeek!</h1>
+ Ruby Programming Language
+ </div>
+ </body>
+</html>
8 example/rules.rb
@@ -0,0 +1,8 @@
+# encoding: utf-8
+
+# filters
+rule Post, "posts/*.html"
+rule Ace::Asset, "assets/**/*"
+
+# generators
+generator TagPagesGenerator#, "/tags/:slug"
0  example/tasks.rb
No changes.
130 lib/ace.rb
@@ -0,0 +1,130 @@
+# encoding: utf-8
+
+# === The boot process === #
+# 1) load the app
+# 2) load the rules (controllers / globs mapping)
+# 3) load & instantiate all the renderable items
+# 4) render all the items (here the filters & layouting run)
+# 5) match the routes, write the files
+
+require "yaml"
+require "fileutils"
+
+module Ace
+ class RawItem
+ attr_accessor :path, :metadata, :content
+ def initialize(path)
+ @data = File.read(path)
+ end
+
+ def parse
+ pieces = @data.split(/^-{3,5}\s*$/)
+ if pieces.size < 3
+ raise RuntimeError.new(
+ "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."
+ )
+ end
+
+ # Parse
+ self.metadata = YAML.load(pieces[1]).inject(Hash.new) { |metadata, pair| metadata.merge(pair[0].to_sym => pair[1]) } || Hash.new
+ self.content = pieces[2..-1].join.strip
+ end
+ end
+
+ # This class represents the items which will be
+ # eventually rendered like concrete posts, tags etc.
+ class Item
+ @@subclasses ||= Array.new
+ def self.inherited(subclass)
+ @@subclasses << subclass
+ end
+
+ @@instances ||= Array.new
+ def self.instances
+ @@instances
+ end
+
+ def self.before_filters
+ @before_filters ||= Array.new
+ end
+
+ def self.before(filter, *args)
+ self.before_filters << filter.new(*args)
+ end
+
+ def self.after_filters
+ @after_filters ||= Array.new
+ end
+
+ def self.after(filter, *args)
+ self.after_filters << filter.new(*args)
+ end
+
+ def self.create(metadata, content)
+ self.new(metadata, content).tap(&:register)
+ end
+
+ # Content can be anything, not just a string.
+ attr_accessor :metadata, :content
+ attr_accessor :original_path
+ def initialize(metadata, content)
+ @metadata = metadata
+ @content = content
+ end
+
+ def config
+ @config ||= begin
+ YAML::load_file("config.yml").inject(Hash.new) do |hash, pair|
+ hash.merge!(pair[0].to_sym => pair[1])
+ end
+ end
+ end
+
+ def register
+ instances = self.class.instances
+ unless instances.include?(self)
+ self.class.instances << self
+ end
+ end
+
+ def unregister
+ self.class.instances.delete(self)
+ end
+
+ def render
+ output = self.class.before_filters.inject(self.content) do |buffer, filter|
+ filter.call(self, buffer)
+ end
+
+ self.class.after_filters.inject(output) do |buffer, filter|
+ filter.call(self, buffer)
+ end
+ end
+
+ attr_writer :output_path
+ def output_path
+ @output_path ||= begin
+ unless self.original_path.nil?
+ self.original_path.sub("content", "output")
+ end
+ end
+ end
+
+ def save!
+ content = self.render.chomp # so filters can influence output_path
+
+ FileUtils.mkdir_p File.dirname(self.output_path)
+ File.open(self.output_path, "w") do |file|
+ file.puts content
+ end
+ end
+ end
+
+ class Asset < Item
+ end
+
+ module Helpers
+ def link_to(anchor, path_or_item, options = nil)
+ end
+ end
+end
21 lib/ace/dsl.rb
@@ -0,0 +1,21 @@
+# encoding: utf-8
+
+module Ace
+ class DSL
+ attr_accessor :rules, :generators
+ def initialize
+ @rules, @generators = Hash.new, Array.new
+ end
+
+ def rule(klass, *globs)
+ paths = globs.map { |glob| Dir.glob("content/#{glob}") }
+ files = paths.flatten.select { |path| File.file?(path) }
+ self.rules[klass] ||= Array.new
+ self.rules[klass].push(*files)
+ end
+
+ def generator(klass)
+ self.generators << klass
+ end
+ end
+end
9 lib/ace/filters.rb
@@ -0,0 +1,9 @@
+# encoding: utf-8
+
+module Ace
+ class Filter
+ def initialize(options = Hash.new)
+ @options = options
+ end
+ end
+end
18 lib/ace/filters/haml.rb
@@ -0,0 +1,18 @@
+# encoding: utf-8
+
+require "haml"
+require "ace/filters"
+
+module Ace
+ class HamlFilter < Filter
+ # http://haml.hamptoncatlin.com/docs/rdoc/classes/Haml/Engine.html
+ def call(item, content)
+ if item.output_path && item.output_path.end_with?(".haml")
+ item.output_path.sub!(/\.haml$/, "")
+ end
+
+ engine = Haml::Engine.new(content)
+ engine.render(item.extend(Ace::Helpers))
+ end
+ end
+end
19 lib/ace/filters/layout.rb
@@ -0,0 +1,19 @@
+# encoding: utf-8
+
+require "ace/filters"
+require "template-inheritance"
+
+TemplateInheritance::Template.paths << File.join(Dir.pwd, "layouts")
+
+module Ace
+ class LayoutFilter < Filter
+ def initialize(options)
+ @path = options[:layout]
+ end
+
+ def call(item, content)
+ template = TemplateInheritance::Template.new(@path)
+ return template.render(item: item)
+ end
+ end
+end
5 lib/ace/version.rb
@@ -0,0 +1,5 @@
+# encoding: utf-8
+
+module Ace
+ VERSION = "0.0.1"
+end
3  project_generator/metadata.yml
@@ -0,0 +1,3 @@
+---
+:full: yes
+:flat: no
9 project_generator/postprocess.rb
@@ -0,0 +1,9 @@
+# encoding: utf-8
+
+# This hook will be executed after templater finish in context of current generator object.
+# Current directory is what you just generated, unless this is flat generator.
+
+unless RUBY_PLATFORM.match(/mswin|mingw/)
+ sh "chmod +x boot.rb"
+ sh "chmod +x tasks.rb"
+end
9 project_generator/setup.rb
@@ -0,0 +1,9 @@
+# encoding: utf-8
+
+# This hook will be executed in context of current generator object before templater start to generate new files.
+# You can update context hash and register hooks. Don't forget to use merge! instead of merge, because you are
+# manipulating with one object, rather than returning new one.
+
+hook do |generator, context|
+ # TODO
+end
6 simple-templater.scope
@@ -0,0 +1,6 @@
+# encoding: utf-8
+
+SimpleTemplater.scope(:ace) do
+ path = File.expand_path("../project_generator", __FILE__)
+ SimpleTemplater.register(:ace, :project, File.expand_path(path))
+end
Please sign in to comment.
Something went wrong with that request. Please try again.