Can extensions replace extractors/transformers/formatters? #420
Replies: 6 comments 12 replies
-
#417 is one step in this direction, allowing for class and view-specific extensions. |
Beta Was this translation helpful? Give feedback.
-
Sub-topic for how we'd release all this without disrupting people's configurations too much. First thought is:
|
Beta Was this translation helpful? Give feedback.
-
I'm overall for making Blueprinter more customisable! And I've suggested a few things myself:
In general, I think blueprinter has such as small scope so I'm not sure a full 'extension system' is needed. Just a few though-out hooks should be enough. Take rails for example (a huge framework), they didn't have an extension system for a long time, but it's very easy to customize. That said, if there is a preference for putting all the hooks into an something called an extension system, I'm not against it. Happy to provide feedback if there is a sketch or code plan of some sort! (public APIs, etc) Some random thoughts:
|
Beta Was this translation helpful? Give feedback.
-
From my experiments in #479: FormattersMake them part of the Blueprint DSL. Specify a class and a block/method, and all field values of that class will be formatted. # Define "global" formats in ApplicationBlueprint.
class ApplicationBlueprint < Blueprinter::V2::Base
format(Date) { |date| date.iso8601 }
format Time, :fmt_time
def fmt_time(t)
t.iso8601
end
end
# Other blueprints can override and define others
class WidgetBlueprint < ApplicationBlueprint
format(Float) { |n| "%.2f" % n }
end |
Beta Was this translation helpful? Give feedback.
-
From my experiments in #479: ExtractorsI really tried to fit this into extension hooks, but it didn't seem like a great fit. I think it's simpler and easier to extend than our current offering, though. Note: class MyBlueprint < ApplicationBlueprint
# Set it for the whole blueprint/view
options[:extractor] = StringKeyHashExtractor
# or on a certain field
field :foo, extractor: StringKeyHashExtractor
end
# An extractor for Hashes with String keys
class StringKeyHashExtractor < Blueprinter::V2::Extractor
# Extract a regular field
def field(context)
if context.object.is_a? Hash
key = context.field.from.to_s
context.object[key]
else
super
end
end
# Extract a belongs_to/has_one type association
def object(context)
field context
end
# Extract a has_many type association
def collection(context)
field context
end
end You can find a proposed implementation of Blueprinter::V2::Extractor here. |
Beta Was this translation helpful? Give feedback.
-
From my experiments in #479: TransformersEntirely hook based. Note: class MyExtension < Blueprinter::Extension
# Called exactly once per render, at the very beginning (when an object is being rendered)
def input_object(context)
# return context.object or a new/modified object
end
# Called exactly once per render, at the very beginning (when a collection is being rendered)
def input_collection(context)
# return context.object or a new/modified object
end
# Returns fields in the order they should be serialized (can also filter out fields)
def blueprint_fields(context)
# default = context.blueprint.class.reflections[:default].ordered
end
# Called right before every Blueprint serialization
def blueprint_input(context)
# return context.object or a new/modified object
end
def exclude_field?(context)
# return true to block the field
end
def exclude_object?(context)
# return true to block the object field
end
def exclude_collection?(context)
# return true to block the collection field
end
def field_value(context)
# return context.value or something else
end
def object_value(context)
# return context.value or something else
end
def collection_value(context)
# return context.value or something else
end
# Called right after every Blueprint serialization. This is probably closest to V1's transformers.
def blueprint_output(context)
# return context.value or a new/modified object
end
# Called exactly once per render, at the very end (when an object is being rendered)
def output_object(context)
# return context.value or a new/modified object
end
# Called exactly once per render, at the very end (when a collection is being rendered)
def output_collection(context)
# return context.value or a new/modified object
end
end |
Beta Was this translation helpful? Give feedback.
-
This is a space to discuss how we might fold Blueprinter's various customization options (extractors, transformers, formatters, etc) into the recently added extension system.
Goals
Beta Was this translation helpful? Give feedback.
All reactions