yajl.rb 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. require 'tilt/template'
  2. module Tilt
  3. # Yajl Template implementation
  4. #
  5. # Yajl is a fast JSON parsing and encoding library for Ruby
  6. # See https://github.com/brianmario/yajl-ruby
  7. #
  8. # The template source is evaluated as a Ruby string,
  9. # and the result is converted #to_json.
  10. #
  11. # == Example
  12. #
  13. # # This is a template example.
  14. # # The template can contain any Ruby statement.
  15. # tpl <<-EOS
  16. # @counter = 0
  17. #
  18. # # The json variable represents the buffer
  19. # # and holds the data to be serialized into json.
  20. # # It defaults to an empty hash, but you can override it at any time.
  21. # json = {
  22. # :"user#{@counter += 1}" => { :name => "Joshua Peek", :id => @counter },
  23. # :"user#{@counter += 1}" => { :name => "Ryan Tomayko", :id => @counter },
  24. # :"user#{@counter += 1}" => { :name => "Simone Carletti", :id => @counter },
  25. # }
  26. #
  27. # # Since the json variable is a Hash,
  28. # # you can use conditional statements or any other Ruby statement
  29. # # to populate it.
  30. # json[:"user#{@counter += 1}"] = { :name => "Unknown" } if 1 == 2
  31. #
  32. # # The last line doesn't affect the returned value.
  33. # nil
  34. # EOS
  35. #
  36. # template = Tilt::YajlTemplate.new { tpl }
  37. # template.render(self)
  38. #
  39. class YajlTemplate < Template
  40. self.default_mime_type = 'application/json'
  41. def self.engine_initialized?
  42. defined? ::Yajl
  43. end
  44. def initialize_engine
  45. require_template_library 'yajl'
  46. end
  47. def prepare
  48. end
  49. def evaluate(scope, locals, &block)
  50. decorate super(scope, locals, &block)
  51. end
  52. def precompiled_preamble(locals)
  53. return super if locals.include? :json
  54. "json = {}\n#{super}"
  55. end
  56. def precompiled_postamble(locals)
  57. "Yajl::Encoder.new.encode(json)"
  58. end
  59. def precompiled_template(locals)
  60. data.to_str
  61. end
  62. # Decorates the +json+ input according to given +options+.
  63. #
  64. # json - The json String to decorate.
  65. # options - The option Hash to customize the behavior.
  66. #
  67. # Returns the decorated String.
  68. def decorate(json)
  69. callback, variable = options[:callback], options[:variable]
  70. if callback && variable
  71. "var #{variable} = #{json}; #{callback}(#{variable});"
  72. elsif variable
  73. "var #{variable} = #{json};"
  74. elsif callback
  75. "#{callback}(#{json});"
  76. else
  77. json
  78. end
  79. end
  80. end
  81. end