templette 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/templette ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+
4
+ usage = <<USAGE
5
+ Generate the templette framework.
6
+ Usage: templette <directory>
7
+ --help gets you this help message... Helpful!
8
+ USAGE
9
+
10
+ require 'fileutils'
11
+
12
+ new_dir = ARGV.first
13
+
14
+ if new_dir.nil? || new_dir.empty?
15
+ puts usage
16
+ exit(0)
17
+ end
18
+
19
+ FileUtils.mkdir(new_dir) unless File.exists?(new_dir)
20
+ %w{/pages /templates /helpers /resources}.each do |dir|
21
+ FileUtils.mkdir(new_dir + dir) unless File.exists?(new_dir + dir)
22
+ end
23
+
24
+ FileUtils.cp(File.dirname(__FILE__) + '/../files/Rakefile', new_dir + '/Rakefile')
25
+ FileUtils.cp(File.dirname(__FILE__) + '/../files/default_helper.rb', new_dir + '/helpers/default_helper.rb')
data/bin/templette.cmd ADDED
@@ -0,0 +1 @@
1
+ @ruby "c:/ruby/bin/templette" %*
data/files/Capfile ADDED
@@ -0,0 +1 @@
1
+ load 'deploy'
data/files/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'rake'
2
+ require 'rubygems'
3
+ gem 'templette'
4
+ require 'templette'
5
+ require 'tasks/templette_tasks'
@@ -0,0 +1,11 @@
1
+ module DefaultHelper
2
+ # Any methods added here will be available to all pages in your site
3
+
4
+ def current_date
5
+ Time.now.strftime('%m/%d/%Y')
6
+ end
7
+
8
+ def current_year
9
+ Time.now.year
10
+ end
11
+ end
data/files/deploy.rb ADDED
@@ -0,0 +1,37 @@
1
+ set :package_name, 'package'
2
+ set :staging_path, ''
3
+ set :user, "username"
4
+
5
+ task :staging do
6
+ role :web, 'staging.example.com'
7
+ set :deploy_path, 'public_html/staging_path'
8
+ end
9
+
10
+ task :production do
11
+ role :web, 'example.com'
12
+ set :deploy_path, 'public_html/path'
13
+ end
14
+
15
+ before "deploy", "deploy:package"
16
+ after "deploy", "deploy:cleanup"
17
+
18
+ namespace :deploy do
19
+
20
+ task :package do
21
+ `rake build destination=#{package_name}`
22
+ `tar -czvf #{package_name}.tar.gz #{package_name}`
23
+ end
24
+
25
+ desc "This is the main task"
26
+ task :default, :roles => [:web] do
27
+ upload "#{package_name}.tar.gz", "#{staging_path}#{package_name}.tar.gz"
28
+ run "tar -xzvf #{staging_path}#{package_name}.tar.gz"
29
+ run "rsync -r #{staging_path}#{package_name}/ #{deploy_path}"
30
+ end
31
+
32
+ task :cleanup do
33
+ run "rm -f #{staging_path}/#{package_name}"
34
+ run "rm -rf #{staging_path}#{package_name}"
35
+ `rm -rf #{package_name}.tar.gz`
36
+ end
37
+ end
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + '/templette'
2
+ module FileGenerator
3
+
4
+ class << self
5
+
6
+ # Called by rake generate:page template=<name> names="<file1 file2>"
7
+ #
8
+ # Generates empty page yaml files in /pages. Takes the methods called in the template and turns them into a yaml framework.
9
+ def page_yaml(template, names)
10
+ template = Templette::Template.new(template)
11
+ names.split(/\s+/).each do |name|
12
+ unless File.exists?("pages/#{name}.yml")
13
+ File.open("pages/#{name}.yml", 'w') {|f| f << template.to_yaml }
14
+ end
15
+ end
16
+ end
17
+
18
+ # Called by rake generate:helper name=<template_name>
19
+ #
20
+ # Generates a helper module in /helpers. A helper will be loaded if it shares the name of the template being applied.
21
+ # To load a different helper, you'll have to include it in default_helper.
22
+ def helper(name)
23
+ helper_name = name =~ /_helper\Z/ ? name : "#{name}_helper"
24
+ module_name = helper_name.split('_').map{|str| str.capitalize}.join
25
+ File.open("helpers/#{helper_name}.rb", 'w') do |f|
26
+ f << "module #{module_name}
27
+ # Add methods for the #{name} template here
28
+ end"
29
+ end
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,47 @@
1
+ desc "Build an HTML project from template files"
2
+ task(:build) do
3
+ Templette::Generator.new(ENV['destination']).run
4
+ end
5
+
6
+ desc "Remove all generated files"
7
+ task :clean do
8
+ Templette::Generator.new.clean
9
+ end
10
+
11
+ namespace :cap do
12
+
13
+ desc "Install the basic capistrano recipes and Capfile"
14
+ task :install do
15
+ files_dir = File.dirname(__FILE__) + '/../../files/'
16
+ %w{Capfile deploy.rb}.each do |file|
17
+ FileUtils.cp(files_dir + file, file) unless File.exists?(file)
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ namespace :generate do
24
+
25
+ desc "Generate empty page files based upon template= and names="
26
+ task :page_yaml do
27
+ unless ENV['template'] && ENV['names']
28
+ puts "You must set template and names to run this task."
29
+ return
30
+ end
31
+ require 'file_generator'
32
+ FileGenerator.page_yaml(ENV['template'], ENV['names'])
33
+ end
34
+
35
+ desc "Generate an empty generator file with name=example"
36
+ task :helper do
37
+ unless ENV['name']
38
+ puts "You must enter a name for your helper."
39
+ return
40
+ end
41
+ require 'file_generator'
42
+ FileGenerator.helper(ENV['name'])
43
+ end
44
+
45
+ end
46
+
47
+ task :default => :build
data/lib/templette.rb ADDED
@@ -0,0 +1,5 @@
1
+ %w{erb yaml fileutils}.each {|lib| require lib}
2
+
3
+ %w{data_accessors errors generator method_collector page template}.each do |file|
4
+ require File.dirname(__FILE__) +"/templette/#{file}"
5
+ end
@@ -0,0 +1,40 @@
1
+ module Templette
2
+ module DataAccessors
3
+ def attributes
4
+ @attributes ||= {}
5
+ end
6
+
7
+ def generate_accessors(accessors = {})
8
+ accessors.each_pair { |k,v| generate_accessor(k, v) }
9
+ end
10
+
11
+ def include_helpers(helpers)
12
+ helpers.each { |helper| add_helper(helper) }
13
+ end
14
+
15
+ def method_missing(symbol)
16
+ raise PageError.new(page, "No method '#{symbol}' defined in the yaml")
17
+ end
18
+
19
+ private
20
+
21
+ def generate_accessor(k, v)
22
+ raise TempletteError.new(page, "Method already defined: #{k}. Change your config file and stop using it!") if self.methods.include?(k.to_s)
23
+ if v.kind_of?(Hash)
24
+ v = Page::Section.new(page, v)
25
+ elsif v =~ /file:(.*)/
26
+ raise PageError.new(page, "File requested by :#{k} no found!") unless File.exists?($1)
27
+ v = File.open($1) {|f| f.read}
28
+ end
29
+ attributes[k.to_s] = v
30
+ instance_eval "def #{k.to_s}; attributes['#{k.to_s}']; end"
31
+ end
32
+
33
+ def add_helper(helper)
34
+ if File.exists?("helpers/#{helper}.rb")
35
+ require "helpers/#{helper}"
36
+ extend Object.module_eval("::#{helper.split('_').map {|str| str.capitalize}.join}", __FILE__, __LINE__)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,20 @@
1
+ module Templette
2
+ class TempletteError < Exception
3
+
4
+ def initialize(error_source, message = nil)
5
+ @error_source = error_source
6
+ @message = message
7
+ end
8
+
9
+ def to_s
10
+ "#{self.class.name.split('::').last} - #{@error_source.name}: #{@message}"
11
+ end
12
+ end
13
+
14
+ class TemplateError < TempletteError # :nodoc:
15
+ end
16
+
17
+ class PageError < TempletteError # :nodoc:
18
+ end
19
+
20
+ end
@@ -0,0 +1,39 @@
1
+ module Templette
2
+ class Generator
3
+ def initialize(out_dir = 'out', resources_dir = 'resources')
4
+ @out_dir = out_dir
5
+ @resources_dir = resources_dir
6
+ @errors = []
7
+ end
8
+
9
+ def run
10
+ FileUtils.mkdir(@out_dir) unless File.exists?(@out_dir)
11
+ pages = Page.find_all
12
+ puts "Generating site in: #{@out_dir}; contains #{pages.size} pages"
13
+ pages.each do |page|
14
+ puts "Generating page #{page.name} using template #{page.template.name}"
15
+ begin
16
+ page.generate(@out_dir)
17
+ rescue Templette::TempletteError => e
18
+ @errors.push(e)
19
+ end
20
+ end
21
+
22
+ if File.exists?(@resources_dir)
23
+ puts "Copying resources from #{@resources_dir} to #{@out_dir}"
24
+ FileUtils.cp_r("#{@resources_dir}/.", @out_dir)
25
+ end
26
+
27
+ if @errors.empty?
28
+ puts "Site generation complete!"
29
+ else
30
+ puts "SITE GENERATED WITH ERRORS!"
31
+ @errors.each { |e| puts e.message }
32
+ end
33
+ end
34
+
35
+ def clean
36
+ FileUtils.rm_rf(@out_dir) if File.exists?(@out_dir)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,28 @@
1
+ require 'erb'
2
+
3
+ module Templette
4
+ # Loads a template and evaluates it with ERB. When a missing method is found,
5
+ # MethodColletor loads that method into a hash, to be rendered as yaml.
6
+ class MethodCollector
7
+ include Templette::DataAccessors
8
+
9
+ def initialize(template = nil)
10
+ include_helpers(template.helpers) if template
11
+ @methods = {}
12
+ ERB.new(template.to_html, 0, "%<>").result(binding) if template
13
+ end
14
+
15
+ def method_missing(symbol)
16
+ @methods[symbol.to_s] = MethodCollector.new
17
+ end
18
+
19
+ def to_hash
20
+ return nil if @methods.empty?
21
+ hash = {}
22
+ @methods.each_pair do |k, v|
23
+ hash[k] = v.to_hash
24
+ end
25
+ hash
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,88 @@
1
+ module Templette
2
+
3
+ # The Page is the core object of a Templette project. Pages won't get generate
4
+ # unless there are available .yml files to build out the necessary info.
5
+ #
6
+ # A general Page yaml structure example:
7
+ #
8
+ # template_name: main
9
+ # sections:
10
+ # title: Page Title
11
+ # nav:
12
+ # active-class: foo
13
+ # title: Foo!
14
+ #
15
+ # The <tt>template_name</tt> will be used to load a template.
16
+ #
17
+ # Everything in <tt>sections</tt> will be made available as methods in the template when
18
+ # it's evaluated by ERB. Yaml hash items nested within others will be loaded into nested
19
+ # objects. To call the nav title, the template should call <tt>nav.title</tt>.
20
+
21
+ class Page
22
+
23
+ include Templette::DataAccessors
24
+ attr_reader :name, :template
25
+
26
+ class <<self
27
+ def pages_dir
28
+ @@pages_dir ||= 'pages'
29
+ end
30
+
31
+ def pages_dir=(path)
32
+ @@pages_dir = path
33
+ end
34
+
35
+ # Grabs all of the yaml files found in /pages, and loads them as
36
+ # Page objects.
37
+ def find_all
38
+ Dir["#{pages_dir}/**/*.yml"].map {|f| new f }
39
+ end
40
+ end
41
+
42
+ def initialize(page_config)
43
+ raise PageError.new(self, "missing page #{page_config}") unless File.exists?(page_config)
44
+
45
+ data = YAML::load_file(page_config)
46
+ @name = page_config.dup
47
+ @name.slice!(self.class.pages_dir + '/')
48
+ @name.chomp!('.yml')
49
+ raise PageError.new(self, "missing required section \"template_name\" for page config #{page_config}") unless data['template_name']
50
+ @template = Template.new(data['template_name'])
51
+
52
+ raise PageError.new(self, "missing sections in yml for page config #{page_config}") unless data['sections']
53
+ generate_accessors(data['sections'])
54
+ include_helpers(template.helpers)
55
+ end
56
+
57
+ def generate(out_dir)
58
+ generate_subdirectory(out_dir)
59
+ File.open(output_file_name(out_dir), 'w') do |f|
60
+ f << ERB.new(@template.to_html, 0, "%<>").result(binding)
61
+ end
62
+ end
63
+
64
+ # A requriement of the Templette::DataAccessors interface. Returns self.
65
+ def page; self end
66
+
67
+ private
68
+
69
+ def output_file_name(out_dir)
70
+ "#{out_dir}/#{@name}.html"
71
+ end
72
+
73
+ def generate_subdirectory(out_dir)
74
+ FileUtils.mkdir_p(File.expand_path("#{out_dir}/" + name.chomp(File.basename(name)))) if name.index('/')
75
+ end
76
+
77
+ class Section # :nodoc:
78
+ include Templette::DataAccessors
79
+ attr_reader :page
80
+
81
+ def initialize(page, hash={})
82
+ @page = page
83
+ generate_accessors(hash)
84
+ end
85
+
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,36 @@
1
+ module Templette
2
+ # The Template acts as a layout for pages. It contains an html layout for the
3
+ # page and contains method calls which are answered by helper methods or the
4
+ # loaded yaml of a page.
5
+
6
+ class Template
7
+ TEMPLATE_DIR = 'templates' unless defined?(TEMPLATE_DIR)
8
+ attr_accessor :name
9
+
10
+ # The name parameter refers to the actual filename of the template. To load
11
+ # templates/foo.html, a template_name of 'foo' should be given.
12
+ def initialize(name)
13
+ @name = name
14
+ end
15
+
16
+ def to_html
17
+ raise TemplateError.new(self, "Template rendering failed. File not found.") unless File.exists?(path)
18
+ File.read(path)
19
+ end
20
+
21
+ # Generates the yaml necessary to render empty page yaml files.
22
+ def to_yaml
23
+ {'template_name' => @name, 'sections' => MethodCollector.new(self).to_hash}.to_yaml
24
+ end
25
+
26
+ # Provides the names of helper_modules to be loaded for a template.
27
+ def helpers
28
+ ["default_helper","#{name}_helper"]
29
+ end
30
+
31
+ private
32
+ def path
33
+ "#{TEMPLATE_DIR}/#{@name}.html"
34
+ end
35
+ end
36
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: templette
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Jacob Dunphy and Steve Holder
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-08-26 00:00:00 -07:00
13
+ default_executable: templette
14
+ dependencies: []
15
+
16
+ description: HTML site generation through templates
17
+ email: jacob.dunphy@gmail.com
18
+ executables:
19
+ - templette
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/file_generator.rb
26
+ - lib/tasks/templette_tasks.rb
27
+ - lib/templette/data_accessors.rb
28
+ - lib/templette/errors.rb
29
+ - lib/templette/generator.rb
30
+ - lib/templette/method_collector.rb
31
+ - lib/templette/page.rb
32
+ - lib/templette/template.rb
33
+ - lib/templette.rb
34
+ - bin/templette
35
+ - bin/templette.cmd
36
+ - files/Capfile
37
+ - files/default_helper.rb
38
+ - files/deploy.rb
39
+ - files/Rakefile
40
+ has_rdoc: true
41
+ homepage: http://github.com/jdunphy/templette
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project: templette
62
+ rubygems_version: 1.2.0
63
+ signing_key:
64
+ specification_version: 2
65
+ summary: HTML site generation through templates
66
+ test_files: []
67
+