Changeset 80
- Timestamp:
- 10/03/2006 15:57:42 (2 years ago)
- Location:
- trunk
- Files:
-
- 6 modified
-
CHANGELOG (modified) (1 diff)
-
README (modified) (6 diffs)
-
Rakefile (modified) (1 diff)
-
lib/markaby.rb (modified) (1 diff)
-
lib/markaby/builder.rb (modified) (3 diffs)
-
lib/markaby/tags.rb (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/CHANGELOG
r20 r80 1 = 0.5 2 === 03 October, 2006 3 4 * XHTML Validation built in. So, if you have an invalid tag: error. Invalid attribute: error. 5 And two identical IDs in the same document: error. Optional, of course. But handy! 6 * New Markaby::Fragment class adds much flexibility. If it discovers you are using a tag as a string, 7 the tag is removed from the stream. (<tt>div { strong("Real") + " Giraffes" }</tt>) 8 * The prevailing rule now is: if you want it escaped, pass it to a block. If not, pass it as an arg. 9 * Again, escaped: <tt>h1("Me & You Have a Giraffe")</tt> 10 * And, not escaped: <tt>h1 { "<a href='/'>Home</a>" }</tt> 11 * Less method_missing, meaning: faster calls all around. Tag methods generated based on doctype. 12 * The <tt>html</tt> method doesn't write the doctype tags and meta tags. You must use <tt>xhtml_transitional</tt> or <tt>xhtml_strict</tt> methods to do that. 13 * The <tt>img</tt> method doesn't try to inject an empty alt tag and a zero border. No more of that. 14 1 15 = 0.3 2 16 === 02nd February, 2006 -
trunk/README
r60 r80 74 74 module where it won't mix with anything. 75 75 76 = A Note About Rails Helpers 77 78 When used in Rails templates, the Rails helper object is passed into 79 Markaby::Builder. When you call helper methods inside Markaby, the output 80 from those methods will be output to the stream. This is incredibly 81 handy, since most Rails helpers output HTML tags. 82 83 head do 84 javascript_include_tag 'prototype' 85 autodiscovery_link_tag 86 end 87 88 However, some methods are designed to give back a String which you can use 89 elsewhere. Call the <tt>@helpers</tt> object with the method and you'll get 90 the String back and nothing will be output. 91 92 p "Total is: #{@helper.number_to_human_size @file_bytes}" 93 94 Conversely, you may call instance variables from your controller by using 95 a method and its value will be returned, nothing will be output. 96 97 # Inside imaginary ProductController 98 def list 99 @products = Product.find :all 100 end 101 102 # Inside app/views/product/list.mab 103 products.each do |product| 104 p product.title 105 end 106 107 = A Quick Tour 76 = The Six Steps of Markaby 108 77 109 78 If you dive right into Markaby, it'll probably make good sense, but you're 110 likely to run into a few kinks. Keep these pointers in mind and everything111 will be fine. 112 113 == Element Classes79 likely to run into a few kinks. Why not review these six steps and commit 80 them memory so you can really *know* what you're doing? 81 82 == 1. Element Classes 114 83 115 84 Element classes may be added by hooking methods onto container elements: … … 129 98 </div> 130 99 131 == Element IDs100 == 2. Element IDs 132 101 133 102 IDs may be added by the use of bang methods: … … 147 116 </div> 148 117 149 == Markaby assumes XHTML 1.0 Transitional 150 151 Output defaults to XHTML 1.0 Transitional. To do XHTML 1.0 Strict, 152 try this: 118 == 3. Validate Your XHTML 1.0 Output 119 120 If you'd like Markaby to help you assemble valid XHTML documents, 121 you can use the <tt>xhtml_transitional</tt> or <tt>xhtml_strict</tt> 122 methods in place of the normal <tt>html</tt> tag. 153 123 154 124 xhtml_strict do 155 # innerds 156 end 157 158 == Markaby prevents invalid HTML 159 160 Since Markaby knows which doctype you're using, it checks a big 125 head { ... } 126 body { ... } 127 end 128 129 This will add the XML instruction and the doctype tag to your document. 130 Also, a character set meta tag will be placed inside your <tt>head</tt> 131 tag. 132 133 Now, since Markaby knows which doctype you're using, it checks a big 161 134 list of valid tags and attributes before printing anything. 162 135 … … 166 139 InvalidHtmlError: no such attribute `styl' 167 140 168 == Auto-stringification 141 Markaby will also make sure you don't use the same element ID twice! 142 143 == 4. Escape or No Escape? 144 145 Markaby uses a simple convention for escaping stuff: if a string 146 is an argument, it gets escaped. If the string is in a block, it 147 doesn't. 148 149 This is handy if you're using something like RedCloth or 150 RDoc inside an element. Pass the string back through the block 151 and it'll skip out of escaping. 152 153 div.comment { RedCloth.new(str).to_html } 154 155 But, if we have some raw text that needs escaping, pass it in 156 as an argument: 157 158 div.comment raw_str 159 160 One caveat: if you have other tags inside a block, the string 161 passed back will be ignored. 162 163 div.comment { 164 div.author "_why" 165 div.says "Torpedoooooes!" 166 "<div>Silence.</div>" 167 } 168 169 The final div above won't appear in the output. You can't mix 170 tag modes like that, friend. 171 172 == 5. Auto-stringification 169 173 170 174 If you end up using any of your Markaby "tags" as a string, the … … 192 196 join( " | " ) 193 197 194 == The <tt>tag!</tt> Method198 == 6. The <tt>tag!</tt> Method 195 199 196 200 If you need to force a tag at any time, call <tt>tag!</tt> with the … … 204 208 end 205 209 210 = A Note About Rails Helpers 211 212 When used in Rails templates, the Rails helper object is passed into 213 Markaby::Builder. When you call helper methods inside Markaby, the output 214 from those methods will be output to the stream. This is incredibly 215 handy, since most Rails helpers output HTML tags. 216 217 head do 218 javascript_include_tag 'prototype' 219 autodiscovery_link_tag 220 end 221 222 However, some methods are designed to give back a String which you can use 223 elsewhere. That's okay! Every method returns a Fragment object, which can 224 be used as a string. 225 226 p { "Total is: #{number_to_human_size @file_bytes}" } 227 228 Also see the Quick Tour above, specifically the stuff about auto-stringification. 229 230 If for any reason you have trouble with fragments, you can just 231 call the <tt>@helpers</tt> object with the method and you'll get 232 the String back and nothing will be output. 233 234 p { "Total is: #{@helper.number_to_human_size @file_bytes}" } 235 236 Conversely, you may call instance variables from your controller by using 237 a method and its value will be returned, nothing will be output. 238 239 # Inside imaginary ProductController 240 def list 241 @products = Product.find :all 242 end 243 244 # Inside app/views/product/list.mab 245 products.each do |product| 246 p product.title 247 end 248 206 249 = Credits 207 250 -
trunk/Rakefile
r77 r80 9 9 10 10 REV = File.read(".svn/entries")[/committed-rev="(\d+)"/, 1] rescue nil 11 VERS = ENV['VERSION'] || "0. 4" + (REV ? ".#{REV}" : "")11 VERS = ENV['VERSION'] || "0.5" + (REV ? ".#{REV}" : "") 12 12 13 13 task :default => [:package] -
trunk/lib/markaby.rb
r74 r80 20 20 # proper templating language. 21 21 module Markaby 22 VERSION = '0. 4'22 VERSION = '0.5' 23 23 24 24 class InvalidXhtmlError < Exception; end -
trunk/lib/markaby/builder.rb
r78 r80 162 162 end 163 163 164 # Create XML markup based on the name of the method +sym+. This method is never 165 # invoked directly, but is called for each markup method in the markup block. 166 # 167 # This method is also used to intercept calls to helper methods and instance 164 # This method is used to intercept calls to helper methods and instance 168 165 # variables. Here is the order of interception: 169 166 # 170 # * If +sym+ is a recognized HTML tag, the tag is output 171 # or a CssProxy is returned if no arguments are given. 172 # * If +sym+ appears to be a self-closing tag, its block 173 # is ignored, thus outputting a valid self-closing tag. 167 # * If +sym+ is a helper method, the helper method is called 168 # and output to the stream. 169 # * If +sym+ is a Builder::XmlMarkup method, it is passed on to the builder object. 174 170 # * If +sym+ is also the name of an instance variable, the 175 171 # value of the instance variable is returned. 176 # * If +sym+ is a helper method, the helper method is called 177 # and output to the stream. 178 # * Otherwise, +sym+ and its arguments are passed to tag! 172 # * If +sym+ has come this far and no +tagset+ is found, +sym+ and its arguments are passed to tag! 173 # * If a tagset is found, though, +NoMethodError+ is raised. 174 # 175 # method_missing used to be the lynchpin in Markaby, but it's no longer used to handle 176 # HTML tags. See html_tag for that. 179 177 def method_missing(sym, *args, &block) 180 178 if @helpers.respond_to?(sym, true) && !self.class.ignored_helpers.include?(sym) 181 179 r = @helpers.send(sym, *args, &block) 182 if @output_helpers 180 if @output_helpers and r.respond_to? :to_str 183 181 fragment { @builder << r } 184 182 else … … 196 194 end 197 195 196 # Every HTML tag method goes through an html_tag call. So, calling <tt>div</tt> is equivalent 197 # to calling <tt>html_tag(:div)</tt>. All HTML tags in Markaby's list are given generated wrappers 198 # for this method. 199 # 200 # If the @auto_validation setting is on, this method will check for many common mistakes which 201 # could lead to invalid XHTML. 198 202 def html_tag(sym, *args, &block) 199 203 if @auto_validation and @tagset.self_closing.include?(sym) and block … … 263 267 end 264 268 269 # Every tag method in Markaby returns a Fragment. If any method gets called on the Fragment, 270 # the tag is removed from the Markaby stream and given back as a string. Usually the fragment 271 # is never used, though, and the stream stays intact. 272 # 273 # For a more practical explanation, check out the README. 265 274 class Fragment < ::Builder::BlankSlate 266 275 def initialize(s, a, b) -
trunk/lib/markaby/tags.rb
r79 r80 7 7 # Common sets of attributes. 8 8 AttrCore = [:id, :class, :style, :title] 9 AttrI18n = [:lang, :'xml:lang', :dir]9 AttrI18n = [:lang, 'xml:lang'.intern, :dir] 10 10 AttrEvents = [:onclick, :ondblclick, :onmousedown, :onmouseup, :onmouseover, :onmousemove, 11 11 :onmouseout, :onkeypress, :onkeydown, :onkeyup] … … 26 26 :title => AttrI18n + [:id], 27 27 :base => [:href, :id], 28 :meta => AttrI18n + [:id, :http, :name, :content, :scheme, :'http-equiv'],28 :meta => AttrI18n + [:id, :http, :name, :content, :scheme, 'http-equiv'.intern], 29 29 :link => Attrs + [:charset, :href, :hreflang, :type, :rel, :rev, :media], 30 :style => AttrI18n + [:id, :type, :media, :title, :'xml:space'],31 :script => [:id, :charset, :type, :src, :defer, :'xml:space'],30 :style => AttrI18n + [:id, :type, :media, :title, 'xml:space'.intern], 31 :script => [:id, :charset, :type, :src, :defer, 'xml:space'.intern], 32 32 :noscript => Attrs, 33 33 :body => Attrs + [:onload, :onunload], … … 42 42 :address => Attrs, 43 43 :hr => Attrs, 44 :pre => Attrs + [ :'xml:space'],44 :pre => Attrs + ['xml:space'.intern], 45 45 :blockquote => Attrs + [:cite], 46 46 :ins => Attrs + [:cite, :datetime], … … 48 48 :a => Attrs + AttrFocus + [:charset, :type, :name, :href, :hreflang, :rel, :rev, :shape, :coords], 49 49 :span => Attrs, 50 :bdo => AttrCore + AttrEvents + [:lang, :'xml:lang', :dir],50 :bdo => AttrCore + AttrEvents + [:lang, 'xml:lang'.intern, :dir], 51 51 :br => AttrCore, 52 52 :em => Attrs,