laydown 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 jbe
1
+ Copyright (c) 2011 jbe
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -14,32 +14,49 @@
14
14
  # | | | oo |
15
15
  #'''''''''''''''''''''''''''''******
16
16
 
17
- # $ gem install laydown
17
+ Bored of writing the same html boilerplate every time you make a new app?
18
18
 
19
- Laydown is a simple template language for defining quick HTML5 layouts in Ruby. Never write the same old boilerplate again.
19
+ How about something like this?
20
+
21
+ # $ gem install laydown
22
+
23
+  
20
24
 
21
25
  require 'laydown'
22
26
 
23
- layout = Laydown.new do |_|
24
- _.charset 'some crazy charset'
25
- _.title 'A man in a cave'
26
- _.description 'A man is sitting in a cave.'
27
- _.keywords 'man, cave, mystery', @keywords
28
- _.favicon '/maninacave.png'
29
- _.css '/maninacave/style.css'
30
- _.css @css, '/site.css'
31
- _.js @js
32
- _.inline_js 'alert("Grrr");'
33
- _.head '<meta generator="FlushFlox Super Deluxe">'
34
- _.ga_code 'UA-8079526-5' # google analytics
35
- _.body_class @body_class
36
- end
37
-
38
- @css = 'somesheet.css'
39
- @body_class = 'front'
40
-
41
- layout.render(self) { '<p>this comes in the body</p>' }
27
+ layout = Laydown.new(
28
+ charset: 'utf-8' # default
29
+ title: 'A man in a #{@where}',
30
+ description: 'Very interesting',
31
+ favicon: 'pill.png',
32
+ keywords: 'man, #{@keywords}',
33
+
34
+ css: ['site.css', '#{@css}'],
35
+ js: ['app.js', '#{@js}'],
36
+ inline_js: ['alert("#{msg}");'],
37
+
38
+ head: '<meta soundtrack="Piazzolla">',
39
+ body: '#{yield}', # default
40
+ body_class: 'dark',
41
+ ga_code: 'ga-some-number'
42
+ )
43
+
44
+ # ----------------------------
45
+
46
+ @where = 'cave'
47
+ @keywords = 'cave, interesting'
48
+ @css = 'somesheet.css'
49
+
50
+ layout.render(self, :msg => 'hello') { '<p>body text</p>' }
42
51
  # => your html5 layout
43
52
 
44
- The block given to `Laydown.new` will be evaluated in the context passed to the `render` method.
53
+ ### Features
54
+
55
+ * Fast
56
+ * Small footprint
57
+ * Built on Temple and Tilt
58
+
59
+ ### Copyright
45
60
 
61
+ Copyright (c) 2011 Jostein Berre Eliassen.
62
+ See LICENCE for details. (MIT licence)
data/Rakefile CHANGED
@@ -5,13 +5,13 @@ begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "laydown"
8
- gem.summary = %Q{Pure Ruby HTML5 layout DSL for microframeworks.}
9
- gem.description = %Q{Provides a simple Ruby DSL for defining HTML5 layouts for web apps. For those of us who has written basically the same html head 200 times and feels like minimalism.}
8
+ gem.summary = %Q{Make HTML5 layouts quickly with plain Ruby.}
9
+ gem.description = %Q{Provides a simple Ruby DSL for defining HTML5 layouts for web apps. For those who has written the same layout too many times.}
10
10
  gem.email = "post@jostein.be"
11
11
  gem.homepage = "http://github.com/jbe/laydown"
12
12
  gem.authors = ["jbe"]
13
- gem.add_dependency "backports" #, ">= 0"
14
- gem.add_development_dependency "tenjin", ">= 0"
13
+ gem.add_dependency "temple" #, ">= 0"
14
+ gem.add_development_dependency "slim", ">= 0"
15
15
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
16
  end
17
17
  Jeweler::GemcutterTasks.new
@@ -20,25 +20,15 @@ rescue LoadError
20
20
  end
21
21
 
22
22
  namespace :build do
23
- desc 'Builds Tenjin templates'
23
+ desc 'Builds slim template'
24
24
  task :template do
25
+ require 'slim'
26
+ src = File.read('template.slim')
27
+ engine = Slim::Engine.new()
28
+ compiled = engine.compile(src)
25
29
 
26
- require 'haml'
27
- src = File.read('template/default.haml')
28
- compiled = Haml::Engine.new(src).precompiled
29
- File.open('lib/laydown/template.rb', 'w') do |f|
30
- f.write <<-RUBY
31
- require 'haml'
32
- #require 'haml/helpers'
33
- #require 'haml/util'
34
- #require 'haml/buffer'
35
- extend Haml::Helpers
36
- _hamlout = @haml_buffer = Haml::Buffer.new(@haml_buffer)
37
- RUBY
38
- f.write(compiled)
39
- f.write "@haml_buffer = @haml_buffer.upper"
30
+ File.open('lib/template.rb', 'w') do |f|
31
+ f.write compiled
40
32
  end
41
-
42
- #sh 'rbtenjin -s templates/default_layout.tenjin.html > lib/templates/default_layout.rb'
43
33
  end
44
34
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.5.0
data/laydown.gemspec CHANGED
@@ -5,12 +5,12 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{laydown}
8
- s.version = "0.4.0"
8
+ s.version = "0.5.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["jbe"]
12
- s.date = %q{2011-02-03}
13
- s.description = %q{Provides a simple Ruby DSL for defining HTML5 layouts for web apps. For those of us who has written basically the same html head 200 times and feels like minimalism.}
12
+ s.date = %q{2011-02-20}
13
+ s.description = %q{Provides a simple Ruby DSL for defining HTML5 layouts for web apps. For those who has written the same layout too many times.}
14
14
  s.email = %q{post@jostein.be}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
@@ -25,12 +25,14 @@ Gem::Specification.new do |s|
25
25
  "VERSION",
26
26
  "laydown.gemspec",
27
27
  "lib/laydown.rb",
28
- "spec/laydown_spec.rb"
28
+ "lib/template.rb",
29
+ "spec/laydown_spec.rb",
30
+ "template.slim"
29
31
  ]
30
32
  s.homepage = %q{http://github.com/jbe/laydown}
31
33
  s.require_paths = ["lib"]
32
34
  s.rubygems_version = %q{1.3.7}
33
- s.summary = %q{Pure Ruby HTML5 layout DSL for microframeworks.}
35
+ s.summary = %q{Make HTML5 layouts quickly with plain Ruby.}
34
36
  s.test_files = [
35
37
  "spec/laydown_spec.rb"
36
38
  ]
@@ -40,15 +42,15 @@ Gem::Specification.new do |s|
40
42
  s.specification_version = 3
41
43
 
42
44
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
- s.add_runtime_dependency(%q<backports>, [">= 0"])
44
- s.add_development_dependency(%q<tenjin>, [">= 0"])
45
+ s.add_runtime_dependency(%q<temple>, [">= 0"])
46
+ s.add_development_dependency(%q<slim>, [">= 0"])
45
47
  else
46
- s.add_dependency(%q<backports>, [">= 0"])
47
- s.add_dependency(%q<tenjin>, [">= 0"])
48
+ s.add_dependency(%q<temple>, [">= 0"])
49
+ s.add_dependency(%q<slim>, [">= 0"])
48
50
  end
49
51
  else
50
- s.add_dependency(%q<backports>, [">= 0"])
51
- s.add_dependency(%q<tenjin>, [">= 0"])
52
+ s.add_dependency(%q<temple>, [">= 0"])
53
+ s.add_dependency(%q<slim>, [">= 0"])
52
54
  end
53
55
  end
54
56
 
data/lib/laydown.rb CHANGED
@@ -1,131 +1,88 @@
1
1
 
2
- require 'backports'
2
+ require 'tilt'
3
+ require 'temple/utils'
3
4
 
4
5
 
5
6
  module Laydown
6
- TOPOBJECT = defined?(BasicObject) ? BasicObject : Object
7
7
 
8
- def self.new(&blk)
9
- Template.new(&blk)
10
- end
11
-
12
- class Template
13
- def initialize(&blk)
14
- @layout = blk
8
+ DEFAULT_TEMPLATE = {
9
+ :charset => 'utf-8',
10
+ :title => nil,
11
+ :description => nil,
12
+ :favicon => nil,
13
+ :keywords => nil,
14
+ :css => [],
15
+ :js => [],
16
+ :inline_js => [],
17
+ :head => [],
18
+ :body_class => nil,
19
+ :body => '#{yield}',
20
+ :ga_code => nil
21
+ }
22
+
23
+ def self.compile(template={})
24
+
25
+ template = DEFAULT_TEMPLATE.merge(template)
26
+
27
+ [:charset, :title, :description, :favicon,
28
+ :keywords, :body_class, :body, :ga_code
29
+ ].each do |k|
30
+ template[k] = case template[k]
31
+ when Array then template[k].join(template[k] == :keywords ? ', ' : '')
32
+ when String then template[k]
33
+ else template[k].to_s
34
+ end
15
35
  end
16
36
 
17
- def render(scope=Object.new, &blk)
18
- dsl = ::Laydown::DSL.new
19
- scope.instance_exec(dsl, &@layout)
20
- Renderer.new(dsl._captured_values, &blk).render
37
+ [:css, :js, :inline_js, :head].each do |k|
38
+ template[k] = Array(template[k]).flatten.compact
21
39
  end
22
- end
23
-
24
- class DSL
25
- TARGETS = %w{
26
- charset lang title description favicon keywords css js
27
- inline_js head body ga_code body_class
28
- }
29
40
 
30
- attr_reader :_captured_values
31
-
32
- def initialize
33
- @_captured_values = Hash.new { [] }
34
- end
35
-
36
- def _laydown(name, *values)
37
- @_captured_values[name] += values
41
+ compiled = read_raw_template.gsub(/data\[:([a-zA-Z0-9_]+)\]/) do |m|
42
+ val = template[:"#{$1}"]
43
+ case val
44
+ when String then interpolatize(val)
45
+ when nil then 'nil'
46
+ when Array then interpolatize(
47
+ val.map {|v| v.to_s }
48
+ )
49
+ else val.to_s
50
+ end
38
51
  end
39
52
 
40
- TARGETS.each do |name|
41
- class_eval <<-RUBY
42
- def #{name}(*a); _laydown('#{name}', *a); end
43
- RUBY
44
- end
53
+ puts compiled
54
+ compiled
45
55
  end
46
56
 
47
- class Renderer
48
-
49
- def initialize(v)
50
-
51
- @charset = v['charset'].first || 'utf-8'
52
- @lang = v['lang'].first
53
- @title = v['title'].compact.join(' &ndash; ')
54
- @favicon = v['favicon'].first
55
- @description = v['description'].compact.join(' ') if v['description']
56
- @keywords = v['keywords'].compact.join(', ') if v['keywords']
57
- @css = v['css'].compact
58
- @js = v['js'].compact
59
- @inline_js = v['inline_js'].compact
60
- @head = v['head'].compact.join("\n")
61
- @ga_code = v['ga_code'].first
62
- @body_class = v['body_class'].compact.join(' ') if v['body_class']
63
- @body = [block_given? ? yield : nil, v['body']].
64
- flatten.compact.join("\n")
65
- end
57
+ def self.new(hsh={})
58
+ Template.new(hsh)
59
+ end
66
60
 
67
- def render
68
- "<!DOCTYPE html>\n" +
69
- _(:html, {:lang => @lang},
70
- _(:head, {},
71
- _(:meta, {:charset => @charset}) +
72
- _(:title, {}, @title) +
73
- (@favicon ?
74
- _(:link, {:rel => 'shortcut icon', :href => @favicon}) : '') +
75
- (@description ?
76
- _(:meta, {:description => @description}) : '') +
77
- (@keywords ?
78
- _(:meta, {:keywords => @keywords}) : '') +
79
- @css.map do |url|
80
- _(:link, {:rel => :stylesheet, :type => 'text/css', :href => url})
81
- end.join +
82
- @js.map do |url|
83
- _(:script, {:type => 'text/javascript', :src => url}, '')
84
- end.join +
85
- @inline_js.map do |code|
86
- _(:script, {:type => 'text/javascript'}, code)
87
- end.join +
88
- (@ga_code ? google_analytics_js : '') +
89
- @head
90
- ) +
91
- _(:body, {:class => @body_class},
92
- @body
93
- )
94
- )
95
- end
61
+ def self.read_raw_template
62
+ File.read(File.join(
63
+ File.dirname(__FILE__), 'template.rb'
64
+ ))
65
+ end
96
66
 
67
+ def self.interpolatize(obj)
68
+ puts obj
69
+ obj.inspect.gsub(/\\#\{/, '#{')
70
+ end
97
71
 
98
- # html helpers
72
+ class Template < Tilt::Template
99
73
 
100
- def _(name, props={}, contents=nil)
101
- tag_str = name.to_s + prop_str(props)
102
- if contents
103
- "<#{tag_str}>\n#{contents}\n</#{name}>\n"
104
- else
105
- "<#{tag_str}/>\n"
106
- end
74
+ def initialize(hsh)
75
+ super(nil, 1, hsh) { '' } # tilt hack
107
76
  end
108
77
 
109
- def prop_str(hsh)
110
- return '' if hsh.values.compact.empty?
111
- ' ' + hsh.map do |k,v|
112
- "#{k.to_s}='#{v.to_s}'" if v
113
- end.compact.join(' ')
78
+ def prepare
79
+ @src = Laydown.compile(options)
114
80
  end
115
81
 
116
- def google_analytics_js
117
- <<-JS
118
- var _gaq = _gaq || [];
119
- _gaq.push(['_setAccount', '#{@ga_code}']);
120
- _gaq.push(['_trackPageview']);
121
- (function() {
122
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
123
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
124
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
125
- })();
126
- JS
82
+ def precompiled_template(locals)
83
+ @src
127
84
  end
128
-
129
85
  end
130
86
  end
131
87
 
88
+
data/lib/template.rb ADDED
@@ -0,0 +1,46 @@
1
+ _buf = [] ; _temple_pre_tags = /<pre|<textarea/ ; _buf << ("<!DOCTYPE html><html><head>") ;
2
+ ;
3
+ ;
4
+ ; if data[:title] ;
5
+ ; _buf << ("<title>#{data[:title]}"\
6
+ ""\
7
+ "</title>") ; end ; if data[:favicon] ;
8
+ ; _buf << ("<link rel=\"shortcut icon\" url=\"#{Temple::Utils.escape_html((data[:favicon]))}\">"\
9
+ ""\
10
+ "") ; end ; if data[:description] ;
11
+ ; _buf << ("<meta content=\"#{Temple::Utils.escape_html((data[:description]))}\" name=\"description\">"\
12
+ ""\
13
+ "") ; end ; if data[:keywords] ;
14
+ ; _buf << ("<meta content=\"#{Temple::Utils.escape_html((data[:keywords]))}\" name=\"keywords\">"\
15
+ ""\
16
+ "") ; end ; data[:css].flatten.each do |url| ;
17
+ ; unless url == '' ;
18
+ ; _buf << ("<link href=\"#{Temple::Utils.escape_html((url))}\" rel=\"stylesheet\" type=\"text/css\">"\
19
+ ""\
20
+ "") ; end ; end ; data[:js].flatten.each do |url| ;
21
+ ; unless url == '' ;
22
+ ; _buf << ("<script src=\"#{Temple::Utils.escape_html((url))}\" type=\"text/javascript\"></script>"\
23
+ ""\
24
+ "") ; end ; end ; if data[:inline_js] && !data[:inline_js].empty? ;
25
+ ; _buf << ("<script type=\"text/javascript\">") ;
26
+ ; data[:inline_js].flatten.each do |code| ;
27
+ ; unless code == '' ;
28
+ ; _buf << (code) ;
29
+ ;
30
+ ; end ; end ; _buf << ("</script>") ; end ; if data[:head] ;
31
+ ; _buf << (data[:head]) ;
32
+ ;
33
+ ; end ; _buf << ("</head><body class=\"#{Temple::Utils.escape_html((data[:body_class]))}\">"\
34
+ "#{data[:body]}"\
35
+ ""\
36
+ "") ; if data[:ga_code] ;
37
+ ;
38
+ ; _buf << ("<script type=\"text/javascript\">var _gaq = _gaq || [];\n_gaq.push(['_setAccount', '"\
39
+ "#{Temple::Utils.escape_html((data[:ga_code]))}']);\n_gaq.push(['_trackPageview']);\n(function() {\nvar ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;\nga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\nvar s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n})();</script>"\
40
+ ""\
41
+ ""\
42
+ ""\
43
+ ""\
44
+ ""\
45
+ ""\
46
+ "") ; end ; _buf << ("</body></html>") ; _buf = _buf.join
data/spec/laydown_spec.rb CHANGED
@@ -5,25 +5,27 @@ require 'laydown'
5
5
  describe Laydown do
6
6
 
7
7
  subject do
8
- Laydown.new do |_|
9
- _.charset 'iso-piso'
10
- _.title 'Apple sucks'
11
- _.description 'Yes, it does. And so do their fans.'
12
- _.favicon 'applesuck.png'
13
- _.keywords 'apple suck lol'
14
- _.css 'applesuck.css'
15
- _.js 'applesuck.js'
16
- _.inline_js "alert('#{@msg}');"
17
- _.head '<meta generator="Ubuntu">'
18
- _.body @body
19
- _.ga_code 'GA-UGGABUGGA'
20
- end
8
+ Laydown.new(
9
+ charset: 'iso-pam-pa-la-la',
10
+ title: 'Apple sucks #{@reason}',
11
+ description: 'And so do their fans.',
12
+ favicon: 'applesuck.png',
13
+ keywords: 'apple suck lol #{@keywords}',
14
+
15
+ css: ['applesuck.css', '#{@css}'],
16
+ js: ['applesuck.js', '#{@js}'],
17
+ inline_js: 'alert("#{@msg}");',
18
+
19
+ head: '<meta generator="Ubuntu">',
20
+ body: '#{yield}',
21
+ ga_code: 'GA-UGGABUGGA'
22
+ )
21
23
  end
22
24
 
23
25
  it 'generates properly' do
24
- @msg = 'lol @ iPhone'
25
- @body = '<p>Seriously.</p>'
26
- str = subject.render(self)
26
+ @reason = 'just because'
27
+ @msg = 'boo'
28
+ str = subject.render(self) { 'This is the body.' }
27
29
  str.should == nil
28
30
 
29
31
  #str.match(/lang="en"/).should
data/template.slim ADDED
@@ -0,0 +1,45 @@
1
+ ! doctype html
2
+ html
3
+ head
4
+ - if data[:title]
5
+ title == data[:title]
6
+
7
+ - if data[:favicon]
8
+ link rel="shortcut icon" url=data[:favicon]
9
+
10
+ - if data[:description]
11
+ meta name="description" content=data[:description]
12
+
13
+ - if data[:keywords]
14
+ meta name="keywords" content=data[:keywords]
15
+
16
+ - data[:css].flatten.each do |url|
17
+ - unless url == ''
18
+ link rel="stylesheet" type='text/css' href=url
19
+
20
+ - data[:js].flatten.each do |url|
21
+ - unless url == ''
22
+ script type="text/javascript" src=url
23
+
24
+ - if data[:inline_js] && !data[:inline_js].empty?
25
+ script type="text/javascript"
26
+ - data[:inline_js].flatten.each do |code|
27
+ - unless code == ''
28
+ == code
29
+
30
+ - if data[:head]
31
+ == data[:head]
32
+
33
+ body class=data[:body_class]
34
+ == data[:body]
35
+
36
+ - if data[:ga_code]
37
+ javascript:
38
+ var _gaq = _gaq || [];
39
+ _gaq.push(['_setAccount', '#{data[:ga_code]}']);
40
+ _gaq.push(['_trackPageview']);
41
+ (function() {
42
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
43
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
44
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
45
+ })();
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 4
7
+ - 5
8
8
  - 0
9
- version: 0.4.0
9
+ version: 0.5.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - jbe
@@ -14,11 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-02-03 00:00:00 +01:00
17
+ date: 2011-02-20 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: backports
21
+ name: temple
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  none: false
@@ -31,7 +31,7 @@ dependencies:
31
31
  type: :runtime
32
32
  version_requirements: *id001
33
33
  - !ruby/object:Gem::Dependency
34
- name: tenjin
34
+ name: slim
35
35
  prerelease: false
36
36
  requirement: &id002 !ruby/object:Gem::Requirement
37
37
  none: false
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: "0"
44
44
  type: :development
45
45
  version_requirements: *id002
46
- description: Provides a simple Ruby DSL for defining HTML5 layouts for web apps. For those of us who has written basically the same html head 200 times and feels like minimalism.
46
+ description: Provides a simple Ruby DSL for defining HTML5 layouts for web apps. For those who has written the same layout too many times.
47
47
  email: post@jostein.be
48
48
  executables: []
49
49
 
@@ -61,7 +61,9 @@ files:
61
61
  - VERSION
62
62
  - laydown.gemspec
63
63
  - lib/laydown.rb
64
+ - lib/template.rb
64
65
  - spec/laydown_spec.rb
66
+ - template.slim
65
67
  has_rdoc: true
66
68
  homepage: http://github.com/jbe/laydown
67
69
  licenses: []
@@ -93,6 +95,6 @@ rubyforge_project:
93
95
  rubygems_version: 1.3.7
94
96
  signing_key:
95
97
  specification_version: 3
96
- summary: Pure Ruby HTML5 layout DSL for microframeworks.
98
+ summary: Make HTML5 layouts quickly with plain Ruby.
97
99
  test_files:
98
100
  - spec/laydown_spec.rb