Class: SchemaDotOrg::SchemaType

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::API, ActiveModel::Attributes, ActiveModel::Validations, ActiveModel::Validations::Callbacks, StripAttributes
Defined in:
app/models/schema_dot_org/schema_type.rb

Overview

Helper class scoped to SchemaDotOrg.

Constant Summary collapse

ROOT_ATTR =

Root attr.

{ '@context' => 'https://schema.org' }.freeze
UNQUALIFIED_CLASS_NAME_REGEX =

Regex pattern matching unqualified class name.

/([^:]+)$/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attrs = {}) ⇒ SchemaType

Virtus silently ignored unknown keys; ActiveModel::AttributeAssignment raises
UnknownAttributeError. Restore the permissive Virtus behaviour so that callers
constructing schema objects (e.g. seo_helper constants) can pass extra keywords
for attributes that are not yet declared without breaking at load time.

Parameters:

  • attrs (Hash) (defaults to: {})


38
39
40
41
# File 'app/models/schema_dot_org/schema_type.rb', line 38

def initialize(attrs = {})
  known = self.class.attribute_types.keys
  super(attrs.slice(*known.map(&:to_sym), *known.map(&:to_s)))
end

Instance Attribute Details

#id_iriString?

Optional IRI for linking entities across documents/blocks

Returns:

  • (String, nil)


45
46
47
# File 'app/models/schema_dot_org/schema_type.rb', line 45

def id_iri
  @id_iri
end

Class Method Details

.attribute(name, type = ActiveModel::Type::Value.new) ⇒ void

This method returns an undefined value.

Parameters:

  • name (Symbol)

    attribute name

  • type (ActiveModel::Type::Value, Class, Array) (defaults to: ActiveModel::Type::Value.new)

    attribute type



24
25
26
27
28
29
30
# File 'app/models/schema_dot_org/schema_type.rb', line 24

def attribute(name, type = ActiveModel::Type::Value.new, **)
  # Coerce Virtus-style plain-class types (e.g. String, Integer) and
  # Virtus array-of-type syntax (e.g. [ListItem]) to untyped Value so
  # existing subclass declarations continue to work without modification.
  type = ActiveModel::Type::Value.new if (type.is_a?(Class) && !(type < ActiveModel::Type::Value)) || type.is_a?(Array)
  super
end

Instance Method Details

#_to_json_structHash

Default behavior uses attributes defined in the class stripping empties

Returns:

  • (Hash)


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'app/models/schema_dot_org/schema_type.rb', line 93

def _to_json_struct
  s = {}
  if valid?
    # Iterate through our attributes, members that are themselves schemaDotOrg type will be rendeed with their json struct attribute
    attributes.each do |k, v|
      next if v.nil? || (v.respond_to?(:empty?) && v.empty?)

      s[k] = if v.respond_to?(:to_json_struct)
               v.to_json_struct
             elsif v.is_a?(Array)
               v.map { |e| e.respond_to?(:to_json_struct) ? e.to_json_struct : e.to_s }.presence
             elsif v.respond_to?(:iso8601)
               v.iso8601
             else
               v
             end
    end
  else
    message = "Unable to generate json+ld struct for #{self.class.name}, #{errors_to_s}"
    Rails.logger.error message
    ErrorReporting.warning(message, schema_type: self.class.name, errors: errors_to_s)
  end
  s
end

#to_json(pretty: false, as_root: false) ⇒ String

Parameters:

  • pretty (Boolean) (defaults to: false)
  • as_root (Boolean) (defaults to: false)

Returns:

  • (String)


73
74
75
76
77
78
79
80
81
# File 'app/models/schema_dot_org/schema_type.rb', line 73

def to_json(pretty: false, as_root: false)
  structure = as_root ? ROOT_ATTR.merge(to_json_struct) : to_json_struct

  if pretty
    JSON.pretty_generate(structure)
  else
    structure.to_json
  end
end

#to_json_ld(pretty: false) ⇒ String

Parameters:

  • pretty (Boolean) (defaults to: false)

Returns:

  • (String)


66
67
68
# File 'app/models/schema_dot_org/schema_type.rb', line 66

def to_json_ld(pretty: false)
  "<script type=\"application/ld+json\">\n#{to_json(pretty: pretty, as_root: true)}\n</script>"
end

#to_json_structHash

Use the class name to create the "@type" attribute.

Returns:

  • (Hash)


85
86
87
88
89
# File 'app/models/schema_dot_org/schema_type.rb', line 85

def to_json_struct
  base = { '@type' => un_namespaced_classname }
  base['@id'] = id_iri if respond_to?(:id_iri) && id_iri.present?
  base.merge(_to_json_struct.compact)
end

#to_sString

Returns:

  • (String)


53
54
55
56
57
58
59
60
61
62
# File 'app/models/schema_dot_org/schema_type.rb', line 53

def to_s
  json_string = to_json_ld(pretty: !rails_production? && !ENV['SCHEMA_DOT_ORG_MINIFIED_JSON'])

  # Mark as safe if we're in Rails
  if json_string.respond_to?(:html_safe)
    json_string.html_safe
  else
    json_string
  end
end

#un_namespaced_classnameString

Returns the classname without the module namespace.

Returns:

  • (String)

    the classname without the module namespace.



119
120
121
122
123
124
# File 'app/models/schema_dot_org/schema_type.rb', line 119

def un_namespaced_classname
  self.class.name =~ UNQUALIFIED_CLASS_NAME_REGEX
  s = Regexp.last_match(1)
  # Translation map
  { 'FaqPage' => 'FAQPage', 'QaPage' => 'QAPage' }[s] || s
end