Class: ForgetPasswords::Template
- Inherits:
-
Object
- Object
- ForgetPasswords::Template
- Includes:
- XML::Mixup
- Defined in:
- lib/forget-passwords/template.rb
Defined Under Namespace
Classes: Mapper
Instance Attribute Summary collapse
-
#doc ⇒ Object
readonly
Returns the value of attribute doc.
-
#mapper ⇒ Object
readonly
Returns the value of attribute mapper.
-
#modified ⇒ Object
readonly
Returns the value of attribute modified.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Instance Method Summary collapse
-
#initialize(mapper, name, content, modified = Time.now) ⇒ Template
constructor
A new instance of Template.
-
#populate(resp, headers = {}, vars = {}, base: nil) ⇒ Rack::Response
Give us the Rack::Response object and we’ll populate the headers and body for you.
-
#process(vars: {}, base: nil, transform: nil) ⇒ Nokogiri::XML::Document
Perform the variable substitution on the associated document and return it.
-
#serialize(doc, headers = {}, full: false) ⇒ String, ...
Given a document, perform rudimentary content negotiation.
Constructor Details
#initialize(mapper, name, content, modified = Time.now) ⇒ Template
Returns a new instance of Template.
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/forget-passwords/template.rb', line 186 def initialize mapper, name, content, modified = Time.now # boring members @mapper = mapper @name = name @modified = modified # resolve content @doc = case content when Nokogiri::XML::Document then content when IO, Pathname content = mapper.path + content fh = content.respond_to?(:open) ? content.open : content Nokogiri::XML.parse fh when String Nokogiri::XML.parse content else raise ArgumentError, "Not sure what to do with #{content.class}" end end |
Instance Attribute Details
#doc ⇒ Object (readonly)
Returns the value of attribute doc.
184 185 186 |
# File 'lib/forget-passwords/template.rb', line 184 def doc @doc end |
#mapper ⇒ Object (readonly)
Returns the value of attribute mapper.
184 185 186 |
# File 'lib/forget-passwords/template.rb', line 184 def mapper @mapper end |
#modified ⇒ Object (readonly)
Returns the value of attribute modified.
184 185 186 |
# File 'lib/forget-passwords/template.rb', line 184 def modified @modified end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
184 185 186 |
# File 'lib/forget-passwords/template.rb', line 184 def name @name end |
Instance Method Details
#populate(resp, headers = {}, vars = {}, base: nil) ⇒ Rack::Response
Give us the Rack::Response object and we’ll populate the headers and body for you.
305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
# File 'lib/forget-passwords/template.rb', line 305 def populate resp, headers = {}, vars = {}, base: nil if (body, type = serialize( process(vars: vars, base: base), headers, full: true)) #resp.length = body.bytesize # not sure if necessary resp.write body resp.content_type = type else # otherwise 406 lol, the client didn't like any of our responses resp.status = 406 end resp end |
#process(vars: {}, base: nil, transform: nil) ⇒ Nokogiri::XML::Document
Perform the variable substitution on the associated document and return it.
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/forget-passwords/template.rb', line 213 def process vars: {}, base: nil, transform: nil # sub all the placeholders for variables doc = @doc.dup # add doctype if missing doc.create_internal_subset('html', nil, nil) unless doc.internal_subset # set the base URI if base ||= mapper.base if b = doc.at_xpath('(/html:html/html:head/html:base)[1]', XPATHNS) # check for a <base href="..."/> already b['href'] = base.to_s elsif t = doc.at_xpath('(/html:html/html:head/html:title)[1]', XPATHNS) # otherwise check for a <title>, after which we'll plunk it markup spec: { nil => :base, href: base.to_s }, after: t elsif h = doc.at_xpath('/html:html/html:head[1]', XPATHNS) # otherwise check for <head>, to which we will prepend markup spec: { nil => :base, href: base.to_s }, parent: h end end # add xsl transform if present if transform ||= mapper.transform pi = { '#pi' => 'xml-stylesheet', type: 'text/xsl', href: transform.to_s } if t = doc.at_xpath("/processing-instruction('xml-stylesheet')[1]") t = markup spec: pi, replace: t else t = markup spec: pi, before: doc.children.first end end # do the processing instructions doc.xpath("/*//processing-instruction('var')").each do |pi| key = pi.content.delete_prefix(?$).delete_suffix(??).to_sym if vars[key] text = pi.document.create_text_node vars[key].to_s pi.replace text end end # do the attributes doc.xpath(ATTRS_XPATH).each do |attr| attr.content = attr.content.gsub(/\$([A-Z_][0-9A-Z_]*)/) do |key| key = key.delete_prefix ?$ vars[key.to_sym] || "$#{key}" end end doc end |
#serialize(doc, headers = {}, full: false) ⇒ String, ...
Given a document, perform rudimentary content negotiation. Return the resulting string, or nil if no variant was chosen.
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
# File 'lib/forget-passwords/template.rb', line 275 def serialize doc, headers = {}, full: false # XXX TODO go back and make it possible for this method to # return a hash with all the headers etc so i don't have to do # this dumb hack method, type = HTTP::Negotiate.negotiate(headers, { [TO_XML, 'application/xhtml+xml'] => { weight: 1.0, type: 'application/xhtml+xml' }, [TO_HTML, 'text/html'] => { weight: 0.8, type: 'text/html' }, [TO_TEXT, 'text/plain'] => { weight: 0.5, type: 'text/plain' }, }) # no type selected return unless method # warn method.inspect out = [doc.instance_exec(&method), type] full ? out : out.first end |