Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Port custom publishing options to Drupal 8
Comment | File | Size | Author |
---|---|---|---|
#18 | custom_pub.module.txt | 10.97 KB | Daniel Schaefer |
#16 | promotion-options.jpg | 14.94 KB | Daniel Schaefer |
Comments
Comment #2
kevinquillen CreditAttribution: kevinquillen at Velir commentedI started looking in to it a few weeks ago, but I am still learning Drupal 8.
Comment #3
Daniel Schaefer CreditAttribution: Daniel Schaefer commentedComment #4
kevinquillen CreditAttribution: kevinquillen at Velir commentedI see what you mean here, but in the context of creating them dynamically custom options can't be in their own yml files.
So, each action corresponds to a plugin, like node_promote_action:
I can't see how to apply this either in the context of dynamically creating custom pub options (see [#2330631] https://www.drupal.org/node/2330631).
My initial feeling is that custom pub options should be config entities that consist of a title/label and machine name. We can then re-implement the dynamic permissions. As a config entity, we can get these properties along with weight and sortable interface without much of a heavy lift (it appears).
From there, we need to attach it to the node form (and I assume) our own submit handler added on to properly save the state of any custom pubs ticked off. But I think you are right - in order to play nice in the new D8 world, they need to be proper actions. That would ensure that its usable in the core Actions realm, and forthcoming Rules release. To expand on that, CPO should also (IMO) support any content entity, not just nodes - but that can come later.
We also need to adapt the node schema when options are added and removed (add field, drop field) - I think I see a way to do this just glancing at node_update_8002 and node_update_8003 as an example.
I myself am still wrapping my head around a lot of these changes.
Does anyone know if the actions.yml file can define a callback to define dynamic action definitions, the same way permissions.yml can?
Comment #5
kevinquillen CreditAttribution: kevinquillen at Velir commentedThose statuses are stored in node_field_data... how do they get there? I am not seeing it in the node.install or config files of the module.
edit:
Oh, I see. In the Node class under baseFieldDefinitions():
So what is considered best practice in this case? Should we extend this class, call the parent method and then add on our custom publish options like this? Or is there another entry point to use so there is a clear separation of concern?
hook_entity_type_alter / hook_entity_type_build seem close, but it isn't clear which one we should employ. I'd also like to find an OO way to do this, if that is the way things should be in D8. So it seems like you could quickly create a form that 'creates' pub options which are just key|value pairs in a cheap schema in the database, but that feels dirty, and I would like the system to be aware of this without an alter jungle.
I am not 100% certain an 'option' is a config entity, but I think they should be. Creating new CPO options then lets you set:
I think this would help in regards to removing a lot of legacy code from D7. Can anyone weigh in on if this is the correct route to take?
Comment #6
Daniel Schaefer CreditAttribution: Daniel Schaefer commentedYeah I've struggled with that too. I've asked for help over in the core section but no reply yet: https://www.drupal.org/node/2649072.
Config entities is probably the right track already. They could be used to create/edit/order/delete the Publishing Options. There is promising tutorial at Creating Custom Config Entities. I'll take a deeper look into the tutorial and test the code on my machine.
The second part, defining actions and hooking into the node/entity creation process I have no clue yet so I can't comment much on your thoughts there. Maybe someone can interpret the relevant code of the Promotion Option fieldset?
Comment #7
kevinquillen CreditAttribution: kevinquillen at Velir commentedI've done some example custom entities but I have not done anything in regards to altering how an existing one works (in this case, Node). I am struggling to understand what parts of the Node module are a good blueprint for development and what areas may be where they implemented quick solutions to carry on functionality (there are a lot of comments around some functions and methods that make me think that way).
Anyway... this route feels right, then getting CPOs to show on node type forms requires a form alter. At that point, each one should be an entity key (by virtue of hook_entity_type_alter) of the CPO machine name, and then similar code on the node form itself.
Comment #8
Daniel Schaefer CreditAttribution: Daniel Schaefer commentedOkay read your edit just now. baseFieldDefinitions() looks right, good spot!
So if we created a function
would that automatically create a checkbox under the Promotion Option?
Comment #9
kevinquillen CreditAttribution: kevinquillen at Velir commentedAre you able to define actions dynamically like you can with permissions?
See: http://cgit.drupalcode.org/custom_pub/tree/custom_pub.permissions.yml?h=...
Comment #10
kevinquillen CreditAttribution: kevinquillen at Velir commentedComment #11
kevinquillen CreditAttribution: kevinquillen at Velir commentedIt doesn't appear that you can define actions dynamically like you can with permissions.
Comment #12
kevinquillen CreditAttribution: kevinquillen at Velir commentedUpdate: https://www.drupal.org/node/1901216#comment-10808000
#1901216: Modules cannot reliably enhance or alter the node form anymore
Comment #13
kevinquillen CreditAttribution: kevinquillen at Velir commentedMoving on from that, alpha2 has basic functionality of CPO on the backend.
Todo
Auto assign options under 'Promotion Options' on content / or their own tabSet access checks to ensure current user can use the option(s)Ensure Views can correctly filter on these optionsWhat I may need help on
Comment #14
Daniel Schaefer CreditAttribution: Daniel Schaefer commentedGreat job. I've just tested alpha2 on simplytest.me and encountered no problems. In the end the workflow differs not much from creating a boolean field on the node form right now since you still have to add the status in Manage form display (there should be a hint on that after creating the status btw) and it does not show within Promotion Options on the node form and the content list view by default. But considering the changes in core I assume that is the best we can get for now? I like that you've managed to hook into the status list on the node configuration form! Being no programmer I'm having such a hard time understanding what's going on underneath but I'll take a look into your code to see where I may be able to contribute.
Comment #15
kevinquillen CreditAttribution: kevinquillen at Velir commentedWell, I followed how core was creating sticky, status, promoted checkboxes for nodes. They create them as boolean field definitions, which makes sense. But now, if they are just fields and not properties (status is set as an entity key still), do we get the same cost savings that we do in D7? I am not sure yet. It was very fast in D7 because a custom pub option was treated as an extension of the node entity, which meant you didn't attach on a field, two field tables were not created in the db, and left join added for queries against that value. It looks like CPOs are still in just the node table, and two field tables are not created for them. So that should count for something.
I also am having trouble finding a way to set options for specific content types, which using the field definition methods does not seem feasible. You can only set a field to one bundle or target entity, you can't pass an array. So right now, all custom publishing options created show on every single node type, regardless. Maybe that isn't such a big deal, but for UI purposes it would be nice to see only what you're intended to see. Also, each publish option is created and default value is set to FALSE, but that isn't retroactively applied to existing content. I guess that is okay, because if you have thousands of nodes, it is an expensive query to execute. Perhaps we could advise to use VBO or provide a batch form to bulk set nodes to that new value, though that seems kludgy.
Also, with how actions are defined now as plugins, I haven't found a way to dynamically define them so it can be triggered. What I mean by that is, look in the 8.x source for how permissions are created. Granted, permissions are simpler than actions, but I was kind of hoping a similar mechanism existed so we could offer the same functionality for actions that is in previous versions.
The way I grouped them on the content forms was look for promoted options, match the custom pub options in the form and group them in the same form item.
Comment #16
Daniel Schaefer CreditAttribution: Daniel Schaefer commentedI think there is a way to include the custom option(s) in the fieldset. Look at line 183 of core/modules/node/src/NodeForm.php:
For testing purposes I've hard-coded an option [sponsored] into core/modules/node/src/Entity/node.php (around line 430)
and core/modules/node/src/NodeForm.php (around 206):
After cache clear the option did show up at the right place:
(Of course, upon submit an exception occurs. I thought it would be worth sharing anyway:
and
)
Comment #17
kevinquillen CreditAttribution: kevinquillen at Velir commentedI think your errors pertain to how fields are created and then available... I had the same issues when writing the code that created the fields.
Basically, you need:
That should create the field and update the node_field_data table.
As for the grouping(s) it is kind of a pain that "Manage Form Display" does nothing for the containers, this disconnect is somewhat confusing. I think it should be totally controlled from the UI, but I digress.
I've updated the code so that we create our own fieldset in the event that node promotions changes for whatever reason in the future.
Comment #18
Daniel Schaefer CreditAttribution: Daniel Schaefer commentedOkay. So I've implemented my findings into the module. My initial testing was successful. You just add the custom_pub to the form display like usual and it will show within the promotion options group.
I don't know how to make a patch so I'll attach the patched module instead.
Maybe with the help of my findings regarding the database we can manage to eliminate the step of attaching the field to a node form.
EDIT: Just now saw your earlier post. Thanks for the hint. I'll get back to it another time. I think with my last patch we are fine for now?
Comment #19
kevinquillen CreditAttribution: kevinquillen at Velir commentedSo the area I was talking about pertains to adding options to certain node types only, it does not seem that the field storage definitions supports passing multiple bundles in, it only accepts one. So right now, the node type options when creating a publishing option virtually do nothing.
I don't recognize what version your patch is from, try using the latest dev release. That said, custom options now go into their own fieldset to avoid any issues with node core.
Comment #20
Daniel Schaefer CreditAttribution: Daniel Schaefer commentedI'm sorry. It seems we kinda talked past each other here.
Comment #21
Daniel Schaefer CreditAttribution: Daniel Schaefer commentedI obviously didn't know about the dedicated fieldset for CPO. I've used alpha2. Will check out your latest version soon.
Comment #22
kevinquillen CreditAttribution: kevinquillen at Velir commentedI just pushed another change to the dev branch that takes care of setting options into the node form upon creating them.
I'll publish an alpha3 shortly, I don;t see a way to list the dev branch anymore as a download.
Comment #23
Daniel Schaefer CreditAttribution: Daniel Schaefer commentedCool, can't wait to see it!
I still like the idea of having the custom options listed with the core ones but I understand the issue. I'll give the new version a try soon and get back to you.
Comment #24
kevinquillen CreditAttribution: kevinquillen at Velir commentedComment #25
kevinquillen CreditAttribution: kevinquillen at Velir commentedalpha4 is up... you can add configurable action(s) to set an option value on a node. Haven't figured out how to autocreate them yet when creating options, but it at least gets people going with Actions.
Comment #26
kevinquillen CreditAttribution: kevinquillen at Velir commentedI attempted to implement rules action support in the latest dev release.. and while the rules action shows up in the list of actions to perform, unfortunately Rules is still in an unstable build and this area of the UI is not completed so I can't really go much further.
Comment #27
kevinquillen CreditAttribution: kevinquillen at Velir commentedComment #28
kevinquillen CreditAttribution: kevinquillen at Velir commentedMarking as fixed as the main objective has been completed.
Specific features should now be broken out into issues.