Problem/Motivation
The process plugins callback (core) and service (this module) now accept an array of arguments if the option unpack_source is set. What is still missing is an easy way to construct the array to pass to these plugins.
Proposed resolution
Add a process plugin that generates an array based on a template (part of configuration) making the following substitutions:
'source:foo'is replaced by the source propertyfoo.'dest:bar'is replaced by the destination propertybar.'pipeline:'is replaced by the pipeline value.
All three support sub-properties, like source:body/0/value. Any other value is copied directly from the template.
This plugin will provide an alternative, often simpler, to adding constants to the source plugin configuration and to using "pseudo fields" as temporary variables.
Remaining tasks
Add tests.
User interface changes
None
API changes
Add a new process plugin.
Data model changes
None
Issue fork migrate_plus-3440904
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
benjifisherIn #3236774-9: Provide ability to reference current value of process pipeline as a source property, @danflanagan8 pointed out that passing
nullas part of thesourcearray of a process plugin has the effect of inserting the pipeline value.At #3436877: [meeting] Migrate Meeting 2024-03-28 2100Z, @mikelutz said that this behavior is a bug, and we should avoid using it.
The process plugin proposed here is more flexible, and it makes the intention clearer.
I think this process plugin is also more flexible than the one proposed in #3314502: Add wrapper process plugin to wrap/unwrap values in arrays.
Comment #4
benjifisherComment #5
benjifisherComment #6
benjifisherSome more examples, from the doc block:
Generic example:
Prepare an entity reference revision (ERR) field
Here is an example from my current project.
Create a serialized array for the
layout_paragraphsmoduleComment #7
danflanagan8Very excited to see this, @benjifisher! I haven't reviewed the code yet, but my first impression on the name is that we're dangerously close to the core
array_buildplugin! The first best replacement name that jumps out at me would bearray_template.Comment #8
benjifisher@danflanagan8:
Thanks for taking a look!
I added some tests, starting with yours from #3314502: Add wrapper process plugin to wrap/unwrap values in arrays. That way,
wrapplugin can do (withmethod: wrap).When I first wrote this plugin, I called it
array_build, but then I realized the problem. I confess I was not very creative when I turned it intobuild_array, and you are right about the potential for confusion.I can go with
array_template, but other variations are worth considering:array_templatetemplate_arraytemplateOr maybe the name should indicate that it can work with source, destination, and pipeline values.
How do you feel about using the short form "dest" instead of spelling out "destination"?
Comment #9
benjifisherComment #10
benjifisherI changed the plugin ID to
array_template, and I changed the class names (plugin and test classes) to match.Comment #11
benjifisherHere is a more complicated example from my current project. A custom source plugin provides the source field
filtersthat looks something like this:That represents two vocabularies and a few terms from each vocabulary.
Here is the pipeline:
After the first step in the pipeline (
sub_process), the example at the top is converted to this:By default, a process plugin (like
array_template) is applied to each element of a source array. In this example,migration_lookupis a no-op.The
single_valueprocess plugin overrides that default behavior, so the nextarray_templateprepares the input for thecallbackplugin:and so the
callbackplugin returnsor
The last step in the pipeline uses
callbackwithcallable: serializeto serialize that array.Comment #12
danflanagan8I played around with this in Migrate Sandbox with great success. I also took my findings over to one of the related issues. (#3314502: Add wrapper process plugin to wrap/unwrap values in arrays)
I love being able to easily mix string literals with source properties and destination properties and (perhaps best of all) the pipeline value.
The test coverage is expansive, too. And the documentation isn't bad at all. Really nice stuff, @benjifisher.
My only complaint (well, I complained about something else way back in #7 that Benji humored me on) is that I feel weird referring about the trailing colon in
pipeline:. It's a strange thing to type.At the same time, it's consistent with
source:anddest:, though with those you have to put something after the colon. IT's just that withpipeline:you don't have to put anything after the colon and I would naively think that I would rarely put anything after the colon.And what would I suggest in place of that syntax that wouldn't simply be my personal preference just based on my personal tastes?
At the end of the day, I think I've convinced myself that the syntax on the MR is fine. Phew!
EDIT: I should clarify that I requested a couple tiny changes on the MR. This was the "only complaint" I had that wasn't a focused comment on the MR. What can I say, I'm a complainer.
Comment #13
benjifisher@danflanagan8:
I think I fixed all the things you pointed out on the MR.
I agree that
'pipeline:'is awkward. I even considered allowingpipelineas a synonym, but I think the Migrate API already goes too far in making things "convenient". If I did that, then I would have to add test coverage for it, too. In the end, I decided to keep the PHP simple and accept a little ugliness in the YAML for the sake of consistency.Comment #14
danflanagan8This is great stuff. Thanks, @benjifisher!
Comment #17
heddnThxs for the contributions.