commit 4cc4e303abf87ee2f4b601a5c6fb2eb5bd8b8650 Author: Jakub Šťastný aka Botanicus Date: Wed Oct 20 14:42:17 2010 +0100 Initial import diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8265aef --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/*.gem +.DS_Store +.rvmrc diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..47d72f7 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,3 @@ += Version 0.0.1 + * Items + * Generators diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d7935b8 --- /dev/null +++ b/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. diff --git a/README.textile b/README.textile new file mode 100644 index 0000000..08f02b7 --- /dev/null +++ b/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 diff --git a/TODO b/TODO new file mode 100644 index 0000000..1ebd191 --- /dev/null +++ b/TODO @@ -0,0 +1 @@ +- ace-gen myproject diff --git a/ace.gemspec b/ace.gemspec new file mode 100755 index 0000000..4d59a46 --- /dev/null +++ b/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 diff --git a/ace.pre.gemspec b/ace.pre.gemspec new file mode 100755 index 0000000..4ddf9a5 --- /dev/null +++ b/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 diff --git a/bin/ace b/bin/ace new file mode 100755 index 0000000..fbb0d21 --- /dev/null +++ b/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 diff --git a/bin/ace-gen b/bin/ace-gen new file mode 100755 index 0000000..daebe2a --- /dev/null +++ b/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 diff --git a/example/app/posts.rb b/example/app/posts.rb new file mode 100644 index 0000000..93a6239 --- /dev/null +++ b/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 diff --git a/example/app/tags.rb b/example/app/tags.rb new file mode 100644 index 0000000..12d7d7e --- /dev/null +++ b/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 diff --git a/example/boot.rb b/example/boot.rb new file mode 100755 index 0000000..c33c093 --- /dev/null +++ b/example/boot.rb @@ -0,0 +1,6 @@ +#!/usr/bin/env ace +# encoding: utf-8 + +Dir["app/**/*.rb"].each do |file| + load file +end diff --git a/example/config.yml b/example/config.yml new file mode 100644 index 0000000..d98d669 --- /dev/null +++ b/example/config.yml @@ -0,0 +1,2 @@ +title: "" +base_url: "" diff --git a/example/content/assets/css/style.css b/example/content/assets/css/style.css new file mode 100644 index 0000000..5ce768c --- /dev/null +++ b/example/content/assets/css/style.css @@ -0,0 +1 @@ +h1 { color: red; } diff --git a/example/content/assets/js/application.js b/example/content/assets/js/application.js new file mode 100644 index 0000000..51593f0 --- /dev/null +++ b/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."); +}; diff --git a/example/content/index.html.haml b/example/content/index.html.haml new file mode 100644 index 0000000..374ac54 --- /dev/null +++ b/example/content/index.html.haml @@ -0,0 +1,5 @@ +- extends "base.html" + +- Post.each do |post| + %h2= post.title + = post.excerpt diff --git a/example/content/posts.json.rb b/example/content/posts.json.rb new file mode 100644 index 0000000..e69de29 diff --git a/example/content/posts/node-js.html b/example/content/posts/node-js.html new file mode 100644 index 0000000..7cf3eb3 --- /dev/null +++ b/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"] +--- + +

+ 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. +

+ +

+ 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. +

+ +
+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/');
+
+ +

+ From Wikipedia.org. +

diff --git a/example/content/posts/ruby.html b/example/content/posts/ruby.html new file mode 100644 index 0000000..54905d3 --- /dev/null +++ b/example/content/posts/ruby.html @@ -0,0 +1,21 @@ +--- +title: Ruby Programming Language +timestamp: 2010-09-14 +tags: ["Development", "Ruby"] +--- + +

+ 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. +

+ +

+ 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. +

+ +

+ 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. +

+ +

+ From Wikipedia.org. +

diff --git a/example/layouts/base.html.haml b/example/layouts/base.html.haml new file mode 100644 index 0000000..1adb67f --- /dev/null +++ b/example/layouts/base.html.haml @@ -0,0 +1,5 @@ +!!! +%html + %head + %body + #main= block(:body) diff --git a/example/layouts/post.html.haml b/example/layouts/post.html.haml new file mode 100644 index 0000000..7ead0d0 --- /dev/null +++ b/example/layouts/post.html.haml @@ -0,0 +1,5 @@ +- extends "base.html" + +- block(:body) do + %h1 My Coooooool Bloogiiiiseeeeek! + = item.content diff --git a/example/layouts/tag.html.haml b/example/layouts/tag.html.haml new file mode 100644 index 0000000..097b07a --- /dev/null +++ b/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] \ No newline at end of file diff --git a/example/lib/initializer.rb b/example/lib/initializer.rb new file mode 100644 index 0000000..e69de29 diff --git a/example/output/assets/css/style.css b/example/output/assets/css/style.css new file mode 100644 index 0000000..5ce768c --- /dev/null +++ b/example/output/assets/css/style.css @@ -0,0 +1 @@ +h1 { color: red; } diff --git a/example/output/assets/js/application.js b/example/output/assets/js/application.js new file mode 100644 index 0000000..51593f0 --- /dev/null +++ b/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."); +}; diff --git a/example/output/posts/node-js.html b/example/output/posts/node-js.html new file mode 100644 index 0000000..2826ee2 --- /dev/null +++ b/example/output/posts/node-js.html @@ -0,0 +1,32 @@ + + + + +
+

My Coooooool Bloogiiiiseeeeek!

+

+ 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. +

+ +

+ 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. +

+ +
+      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/');
+      
+ +

+ From Wikipedia.org. +

+
+ + diff --git a/example/output/posts/ruby.html b/example/output/posts/ruby.html new file mode 100644 index 0000000..b4ae395 --- /dev/null +++ b/example/output/posts/ruby.html @@ -0,0 +1,24 @@ + + + + +
+

My Coooooool Bloogiiiiseeeeek!

+

+ 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. +

+ +

+ 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. +

+ +

+ 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. +

+ +

+ From Wikipedia.org. +

+
+ + diff --git a/example/output/posts/test.html b/example/output/posts/test.html new file mode 100644 index 0000000..ca32b4f --- /dev/null +++ b/example/output/posts/test.html @@ -0,0 +1,10 @@ + + + + +
+

My Coooooool Bloogiiiiseeeeek!

+ content +
+ + diff --git a/example/output/tags/development.html b/example/output/tags/development.html new file mode 100644 index 0000000..4bd304b --- /dev/null +++ b/example/output/tags/development.html @@ -0,0 +1,11 @@ + + + + +
+

My Coooooool Bloogiiiiseeeeek!

+ Node.js Asynchronous JavaScript Framework + Ruby Programming Language +
+ + diff --git a/example/output/tags/javascript.html b/example/output/tags/javascript.html new file mode 100644 index 0000000..b6c4df9 --- /dev/null +++ b/example/output/tags/javascript.html @@ -0,0 +1,10 @@ + + + + +
+

My Coooooool Bloogiiiiseeeeek!

+ Node.js Asynchronous JavaScript Framework +
+ + diff --git a/example/output/tags/node.js.html b/example/output/tags/node.js.html new file mode 100644 index 0000000..b6c4df9 --- /dev/null +++ b/example/output/tags/node.js.html @@ -0,0 +1,10 @@ + + + + +
+

My Coooooool Bloogiiiiseeeeek!

+ Node.js Asynchronous JavaScript Framework +
+ + diff --git a/example/output/tags/ruby.html b/example/output/tags/ruby.html new file mode 100644 index 0000000..0fd47ae --- /dev/null +++ b/example/output/tags/ruby.html @@ -0,0 +1,10 @@ + + + + +
+

My Coooooool Bloogiiiiseeeeek!

+ Ruby Programming Language +
+ + diff --git a/example/rules.rb b/example/rules.rb new file mode 100644 index 0000000..9b2b107 --- /dev/null +++ b/example/rules.rb @@ -0,0 +1,8 @@ +# encoding: utf-8 + +# filters +rule Post, "posts/*.html" +rule Ace::Asset, "assets/**/*" + +# generators +generator TagPagesGenerator#, "/tags/:slug" diff --git a/example/tasks.rb b/example/tasks.rb new file mode 100755 index 0000000..e69de29 diff --git a/lib/ace.rb b/lib/ace.rb new file mode 100644 index 0000000..70c6d16 --- /dev/null +++ b/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 diff --git a/lib/ace/dsl.rb b/lib/ace/dsl.rb new file mode 100644 index 0000000..b937d91 --- /dev/null +++ b/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 diff --git a/lib/ace/filters.rb b/lib/ace/filters.rb new file mode 100644 index 0000000..834b15c --- /dev/null +++ b/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 diff --git a/lib/ace/filters/haml.rb b/lib/ace/filters/haml.rb new file mode 100644 index 0000000..5676c9e --- /dev/null +++ b/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 diff --git a/lib/ace/filters/layout.rb b/lib/ace/filters/layout.rb new file mode 100644 index 0000000..6dcf769 --- /dev/null +++ b/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 diff --git a/lib/ace/version.rb b/lib/ace/version.rb new file mode 100644 index 0000000..5982e8c --- /dev/null +++ b/lib/ace/version.rb @@ -0,0 +1,5 @@ +# encoding: utf-8 + +module Ace + VERSION = "0.0.1" +end diff --git a/project_generator/metadata.yml b/project_generator/metadata.yml new file mode 100644 index 0000000..005004e --- /dev/null +++ b/project_generator/metadata.yml @@ -0,0 +1,3 @@ +--- +:full: yes +:flat: no diff --git a/project_generator/postprocess.rb b/project_generator/postprocess.rb new file mode 100644 index 0000000..4a3c1aa --- /dev/null +++ b/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 diff --git a/project_generator/setup.rb b/project_generator/setup.rb new file mode 100644 index 0000000..09b0b41 --- /dev/null +++ b/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 diff --git a/simple-templater.scope b/simple-templater.scope new file mode 100644 index 0000000..6488fae --- /dev/null +++ b/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