liquid_interpolatable.rb 2.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. module LiquidInterpolatable
  2. extend ActiveSupport::Concern
  3. included do
  4. validate :validate_interpolation
  5. end
  6. def valid?(context = nil)
  7. super
  8. rescue Liquid::Error
  9. errors.empty?
  10. end
  11. def validate_interpolation
  12. interpolated
  13. rescue Liquid::Error => e
  14. errors.add(:options, "has an error with Liquid templating: #{e.message}")
  15. false
  16. end
  17. def interpolate_options(options, event = {})
  18. case options
  19. when String
  20. interpolate_string(options, event)
  21. when ActiveSupport::HashWithIndifferentAccess, Hash
  22. options.inject(ActiveSupport::HashWithIndifferentAccess.new) { |memo, (key, value)| memo[key] = interpolate_options(value, event); memo }
  23. when Array
  24. options.map { |value| interpolate_options(value, event) }
  25. else
  26. options
  27. end
  28. end
  29. def interpolated(event = {})
  30. key = [options, event]
  31. @interpolated_cache ||= {}
  32. @interpolated_cache[key] ||= interpolate_options(options, event)
  33. @interpolated_cache[key]
  34. end
  35. def interpolate_string(string, event)
  36. Liquid::Template.parse(string).render!(event.to_liquid, registers: {agent: self})
  37. end
  38. require 'uri'
  39. module Filters
  40. # Percent encoding for URI conforming to RFC 3986.
  41. # Ref: http://tools.ietf.org/html/rfc3986#page-12
  42. def uri_escape(string)
  43. CGI.escape(string) rescue string
  44. end
  45. # Escape a string for use in XPath expression
  46. def to_xpath(string)
  47. subs = string.to_s.scan(/\G(?:\A\z|[^"]+|[^']+)/).map { |x|
  48. case x
  49. when /"/
  50. %Q{'#{x}'}
  51. else
  52. %Q{"#{x}"}
  53. end
  54. }
  55. if subs.size == 1
  56. subs.first
  57. else
  58. 'concat(' << subs.join(', ') << ')'
  59. end
  60. end
  61. end
  62. Liquid::Template.register_filter(LiquidInterpolatable::Filters)
  63. module Tags
  64. class Credential < Liquid::Tag
  65. def initialize(tag_name, name, tokens)
  66. super
  67. @credential_name = name.strip
  68. end
  69. def render(context)
  70. credential = context.registers[:agent].credential(@credential_name)
  71. raise "No user credential named '#{@credential_name}' defined" if credential.nil?
  72. credential
  73. end
  74. end
  75. end
  76. Liquid::Template.register_tag('credential', LiquidInterpolatable::Tags::Credential)
  77. end