Module: OpenGraphReader::Object::DSL
- Defined in:
- lib/open_graph_reader/object/dsl.rb,
lib/open_graph_reader/object/dsl/types.rb
Overview
This module provides the methods to define new types and properties, as well as setting other metadata necessary to describe an object, such as its namespace.
Class Method Summary collapse
-
.define_type(name) {|value, *args, options| ... } ⇒ Object
Defines a new DSL method for modeling a new type.
-
.processors ⇒ {Symbol => Proc}
private
A map from type names to processing blocks.
Instance Method Summary collapse
-
#available_properties ⇒ Array<String>
The list of defined properties on this object.
- #boolean(name, options = {}) ⇒ Object
-
#content(type, *args, options = {}) ⇒ Object
Set the type for the content attribute.
-
#content_processor ⇒ Proc
private
The processor for the content attribute.
- #datetime(name, options = {}) ⇒ Object
- #enum(name, allowed, options = {}) ⇒ Object
- #float(name, options = {}) ⇒ Object
- #integer(name, options = {}) ⇒ Object
- #namespace(*names) ⇒ Object
-
#required_properties ⇒ Array<String]
The list of required properties on this object.
- #string(name, options = {}) ⇒ Object
- #url(name, options = {}) ⇒ Object
-
#verticals ⇒ {String => Array<Strin>}
private
A map from vertical names to attributes that belong to them.
Class Method Details
.define_type(name) {|value, *args, options| ... } ⇒ Object
Defines a new DSL method for modeling a new type
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/open_graph_reader/object/dsl.rb', line 32 def self.define_type(name, &processor) processors[name] = processor define_method(name) do |name, *args| = args.pop if args.last.is_a? Hash ||= {} available_properties << name.to_s required_properties << name.to_s if [:required] Registry.register [@namespace, name].join(':'), [:to] if [:to] if [:verticals] [:verticals].each do |vertical| vertical = [@namespace, vertical].join('.') verticals[vertical] << name.to_s Registry.verticals << vertical end end if [:collection] define_method("#{name}s") do children[name.to_s] end define_method(name) do value = children[name.to_s].first # @todo figure out a sane way to distinguish subobject properties value.content if value && value.is_a?(Object) value || [:default] end else define_method(name) do properties[name.to_s] || [:default] end define_method("#{name}=") do |value| # @todo figure out a sane way to distinguish subobject properties unless value.is_a? Object value.downcase! if [:downcase] value = processor.call(value, *args, ) end properties[name.to_s] = value end end end end |
.processors ⇒ {Symbol => Proc}
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
A map from type names to processing blocks.
135 136 137 |
# File 'lib/open_graph_reader/object/dsl.rb', line 135 def self.processors @processors ||= {} end |
Instance Method Details
#available_properties ⇒ Array<String>
The list of defined properties on this object.
120 121 122 |
# File 'lib/open_graph_reader/object/dsl.rb', line 120 def available_properties @available_properties ||= [] end |
#boolean(name, options = {}) ⇒ Object
80 81 82 83 84 85 86 |
# File 'lib/open_graph_reader/object/dsl/types.rb', line 80 define_type :boolean do |value| {'true' => true, 'false' => false, '1' => true, '0' => false}[value].tap {|bool| if bool.nil? raise InvalidObjectError, "Boolean expected, but was #{value.inspect}" end } end |
#content(type, *args, options = {}) ⇒ Object
106 107 108 109 110 111 112 113 114 115 |
# File 'lib/open_graph_reader/object/dsl.rb', line 106 def content type, *args = args.pop if args.last.is_a? Hash ||= {} @content_processor = proc {|value| value.downcase! if [:downcase] [:to] ||= self DSL.processors[type].call(value, *args, ) } end |
#content_processor ⇒ Proc
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The processor for the content attribute.
143 144 145 |
# File 'lib/open_graph_reader/object/dsl.rb', line 143 def content_processor @content_processor end |
#datetime(name, options = {}) ⇒ Object
71 72 73 74 75 76 77 |
# File 'lib/open_graph_reader/object/dsl/types.rb', line 71 define_type :datetime do |value| begin DateTime.iso8601 value rescue ArgumentError => e raise InvalidObjectError, "ISO8601 datetime expected, but was #{value.inspect}" end end |
#enum(name, allowed, options = {}) ⇒ Object
53 54 55 56 57 58 59 |
# File 'lib/open_graph_reader/object/dsl/types.rb', line 53 define_type_no_doc :enum do |value, allowed| unless allowed.include? value raise InvalidObjectError, "Expected one of #{allowed.inspect} but was #{value.inspect}" end value.to_s end |
#float(name, options = {}) ⇒ Object
89 90 91 92 93 94 95 |
# File 'lib/open_graph_reader/object/dsl/types.rb', line 89 define_type :float do |value| begin Float(value) rescue ArgumentError => e raise InvalidObjectError, "Float expected, but was #{value.inspect}" end end |
#integer(name, options = {}) ⇒ Object
62 63 64 65 66 67 68 |
# File 'lib/open_graph_reader/object/dsl/types.rb', line 62 define_type :integer do |value| begin Integer(value) rescue ArgumentError => e raise InvalidObjectError, "Integer expected, but was #{value.inspect}" end end |
#namespace ⇒ String #namespace(*names) ⇒ Object
92 93 94 95 96 |
# File 'lib/open_graph_reader/object/dsl.rb', line 92 def namespace *names return @namespace if names.empty? @namespace = names.join(':') Registry.register @namespace, self end |
#required_properties ⇒ Array<String]
The list of required properties on this object.
127 128 129 |
# File 'lib/open_graph_reader/object/dsl.rb', line 127 def required_properties @required_properties ||= [] end |
#string(name, options = {}) ⇒ Object
10 11 12 |
# File 'lib/open_graph_reader/object/dsl/types.rb', line 10 define_type :string do |value| value.to_s end |
#url(name, options = {}) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/open_graph_reader/object/dsl/types.rb', line 19 define_type_no_doc :url do |value, | value = value.to_s unless value.start_with?('http://') || value.start_with?('https://') if [:image] && OpenGraphReader.config.synthesize_image_url unless OpenGraphReader.current_origin raise ArgumentError, "Enabled image url synthesization but didn't pass an origin" end # Synthesize scheme hack to https (//example.org/foo/bar.png) if value.start_with?('//') && value.split('/', 4)[2] =~ URI::HOST value = "https:#{value}" else # Synthesize absolute path (/foo/bar.png) begin value = "/#{value}" unless value.start_with? '/' # Normalize to absolute path uri = URI.parse(OpenGraphReader.current_origin) uri.path = value value = uri.to_s rescue raise InvalidObjectError, "URL #{value.inspect} does not start with http:// or https:// and failed to synthesize a full URL" end end elsif .has_key?(:to) && OpenGraphReader.config.validate_references raise InvalidObjectError, "URL #{value.inspect} does not start with http:// or https://" end end value end |
#verticals ⇒ {String => Array<Strin>}
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
A map from vertical names to attributes that belong to them.
151 152 153 |
# File 'lib/open_graph_reader/object/dsl.rb', line 151 def verticals @verticals ||= Hash.new {|h, k| h[k] = [] } end |