Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2021-06-17 08:25:47

albatros69
Member
Registered: 2021-06-17
Posts: 21

Adding an action for specific articles

Hello,

To help a publisher team and automatize some actions, I want to develop a small plugin for their Textpattern. The requirements are not complex:
  • add an action in the “Write” panel (could be also in the articles panel, adding a “multi_edited” action) ;
  • on this action, trigger some code from the extension, getting somehow the article as a parameter. In particular, I will need to persist back some values to the selected article (using custom fields I guess).

I’ve read the plugin documentation and I’m trying to figure out what could be the most suitable solution. Currently, I’m a bit stuck because my use-case doesn’t seem to fit in the callback mechanism as I’m trying to create a new action. And I didn’t find a mean yet, to create such a “new” action.

Thanks in advance for your help,

Offline

#2 2021-06-17 09:02:03

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,269
Website GitHub

Re: Adding an action for specific articles

Hello and welcome to the forum.

To add stuff to the UI, take a look at the pluggable_ui() callbacks. You can either add to or alter the markup in each area of the panel. There’s a specific one called ‘article_ui > extend_col_1’ which is where you can add a completely new area, or use one of the existing areas and modify what it displays.

With regards functionality, you can hook into the article save callback process if you need to do something when an article is posted/modifed. But if you’re presenting this on a ‘new’ article, the ID won’t have been assigned yet so the only data available to you will be what is currently in the boxes on-screen (i.e. not in the database) so you’ll be limited to JavaScript to get at the data. After save, the article will have an entry in the database so you’ll be able to access any information that way.

For multi-edit callbacks, you can add new functionality there no problem. Just add your item and any additional markup to display when the control is selected.

To process the results of users selecting your new action, you’ll need to hook into the (currently undocumented, oops – I’ll fix that) multi_edit.{your_action} callback. You’ll need to handle the entire action yourself there because, from what I recall in the code, the callback isn’t optimised for performing the action and then returning for Textpattern to carry on displaying the UI. Bit of a shortcoming (sorry) but I’m gradually trawling through all the callbacks and revamping their names and scopes for Textpattern v4.9.0. So as part of that initiative it may be possible to be more clever here.

Hope that helps, but please continue this discussion if you need any further assistance.

Last edited by Bloke (2021-06-17 09:04:01)


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#3 2021-06-17 10:28:30

albatros69
Member
Registered: 2021-06-17
Posts: 21

Re: Adding an action for specific articles

Thanks for the answer!

Bloke wrote #330520:

With regards functionality, you can hook into the article save callback process if you need to do something when an article is posted/modifed. But if you’re presenting this on a ‘new’ article, the ID won’t have been assigned yet so the only data available to you will be what is currently in the boxes on-screen (i.e. not in the database) so you’ll be limited to JavaScript to get at the data. After save, the article will have an entry in the database so you’ll be able to access any information that way.

My real problem is that I can’t completely hook into the save process. More precisely, I need the article to exist, so as you said, there’s a need to a prior save. Ideally, the action would appear only if the save has already occurs. Then, if it’s the case and if the user click on a specific button, my real action would be triggered on the saved article.

For multi-edit callbacks, you can add new functionality there no problem. Just add your item and any additional markup to display when the control is selected.

To process the results of users selecting your new action, you’ll need to hook into the (currently undocumented, oops – I’ll fix that) multi_edit.{your_action} callback. You’ll need to handle the entire action yourself there because, from what I recall in the code, the callback isn’t optimised for performing the action and then returning for Textpattern to carry on displaying the UI. Bit of a shortcoming (sorry) but I’m gradually trawling through all the callbacks and revamping their names and scopes for Textpattern v4.9.0. So as part of that initiative it may be possible to be more clever here.

I will look into that. That’s seems also a good way to do what I need.

Offline

#4 2021-06-17 11:47:02

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,269
Website GitHub

Re: Adding an action for specific articles

albatros69 wrote #330523:

Ideally, the action would appear only if the save has already occurs. Then, if it’s the case and if the user click on a specific button, my real action would be triggered on the saved article.

That’s doable. In your pluggable_ui() callback that renders the control, check if the passed database record is populated and/or contains an ‘ID’ (e.g. $rs['ID'] is not empty – the record content is usually passed as argument #4 to your callback).

If it’s empty, just return, otherwise you know you have an article in the DB and you can append your action element to the existing content.


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#5 2021-06-17 13:27:20

albatros69
Member
Registered: 2021-06-17
Posts: 21

Re: Adding an action for specific articles

Bloke wrote #330527:

That’s doable. In your pluggable_ui() callback that renders the control, check if the passed database record is populated and/or contains an ‘ID’ (e.g. $rs['ID'] is not empty – the record content is usually passed as argument #4 to your callback).

If it’s empty, just return, otherwise you know you have an article in the DB and you can append your action element to the existing content.

Seems perfect. If I use this to add a button next to “Save”, how would I catch the event that the user has clicked on the button (apart from doing it in JavaScript, which I would like to avoid)? Can I register a new event that will be associated to the user submitting the form by clicking on this button?

I looked into other plugins to learn the best practices, but what I’ve seen so far are solutions based on JS (yab_copy_to_new e.g.).

Last edited by albatros69 (2021-06-17 13:32:15)

Offline

#6 2021-06-17 13:40:17

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,269
Website GitHub

Re: Adding an action for specific articles

Ah, now if you’re adding alongside the Save button, that’s an anomaly. It’s considered “static” by Textpattern so your plugin will not get retriggered when the Ajax save is performed. That may be why plugins that do this resort to JS.

The closest you can probably do is hook into the ‘actions’ area beneath the Save button, where the Duplicate and View links are. That’s treated as “volatile” by core and thus is updated on every save.

One thing you could do, btw (I’ve never done it myself so YMMV) is hook into article_ui>partials_meta. That allows direct access to the entire array of partials (bits of the UI) that Textpattern is going to handle on the Write panel. The 3rd parameter is the database record set containing the contents of the UI elements, and the 4th parameter passed to the plugin is the partials array itself.

In theory, you could manipulate this array – even add to it – and register your own (sub)area. Quite how that would work is something I’ve never tried so it’d be interesting to find out how well it works. The callback is there to be (ab)used!


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#7 2021-06-17 13:44:42

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,269
Website GitHub

Re: Adding an action for specific articles

And in answer to your actual question… (ahem)…

Look at asyncHref() and Route.add() in textpattern.js. If you fashion an anchor with a particular class in the admin side, it’ll automatically get picked up by our async save process. So any click will perform that action and bundle any new data up for the ride.

If you alter the ‘step’ value you pass in with your link, you can then intercept it in the plugin and deal with just your bit, leaving the rest for core to worry about.


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#8 2021-06-22 16:11:01

albatros69
Member
Registered: 2021-06-17
Posts: 21

Re: Adding an action for specific articles

Hello,

I’ve progressed significantly, thanks to your kind help.
I have now added, using a callback on article_ui>inputlabel.custom-*, an action button next to the custom field that will be changed by the very action triggered by the user. The hurdle here is that I don’t have access to the article record in this callback (to hide the button in case the article has not been saved yet), so I started to look into another callback to do that in JS. The best would be admin_side>body_end (because of JS), but the record is not passed to this callback either.

Do you see a potential solution here? I’m under the impression that the article record is only passed to specific callbacks, e.g. the pluggable_ui ones, and I’m unable to choose the best one (maybe partials_meta you mentioned already).

Secondly, is it possible to “create” a new article’s step corresponding to the user clicking on my custom button? I’ve tried to alter the hidden field before submitting the form, but the callback I’ve declared to handle the new step doesn’t seem to be reached at all.

Last edited by albatros69 (2021-06-22 16:45:30)

Offline

#9 2021-06-22 16:34:19

etc
Developer
Registered: 2010-11-11
Posts: 5,053
Website GitHub

Re: Adding an action for specific articles

albatros69 wrote #330612:

Secondly, is it possible to “create” a new article’s step corresponding to the user clicking on my custom button? I’ve tried to alter the hidden field before submitting the form, but the callback I’ve declared to handle the new step doesn’t seem to be reached at all.

Hello,

as I get it, global $event calls the corresponding include/txp_{event}.php file, and $step invokes some function inside this file. So, they must ‘exist’ in some sense, to function properly. Still, you can intercept these calls, by registering your plugin on ($event, $step, 1) (1 is the key here), doing what needed and resetting global $step to some txp-meaningful value. Past this callback, it is too late, txp takes the lead.

You can also do something directly in your plugin, without registering any callback.

Offline

#10 2021-06-22 19:53:31

albatros69
Member
Registered: 2021-06-17
Posts: 21

Re: Adding an action for specific articles

etc wrote #330613:

as I get it, global $event calls the corresponding include/txp_{event}.php file, and $step invokes some function inside this file. So, they must ‘exist’ in some sense, to function properly. Still, you can intercept these calls, by registering your plugin on ($event, $step, 1) (1 is the key here), doing what needed and resetting global $step to some txp-meaningful value. Past this callback, it is too late, txp takes the lead.

You can also do something directly in your plugin, without registering any callback.

The way you phrase it, it seems kind of a hack :-), and as I’m new to txp plugin development, I’m uncomfortable to do it unless this is the only way to somehow handle a new action triggered by the user. I’m still trying to workout something, by piggybacking on the save process, to have something more standard and thus more maintainable.

Offline

#11 2021-06-22 20:08:51

etc
Developer
Registered: 2010-11-11
Posts: 5,053
Website GitHub

Re: Adding an action for specific articles

albatros69 wrote #330616:

I’m uncomfortable to do it unless this is the only way to somehow handle a new action triggered by the user.

It’s about the only way if you want to create a ‘standard’ new step, but nothing stops you from introducing another hidden field, say my_step, register a callback wherever needed, retrieve my_step value (gps('my_step')) and act accordingly. The details depend on what you want to achieve.

Offline

#12 2021-06-22 20:21:07

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,269
Website GitHub

Re: Adding an action for specific articles

albatros69 wrote #330616:

The way you phrase it, it seems kind of a hack :-)

Hehe, it’s not a hack. It’s an officially supported thing, it’s just… not the prettiest way of doing things!

Hooking into pre=1 means your plugin gets processed first before Textpattern gets involved. So if you pass a new step in, you can check it in your code, handle it and then either let Txp carry on, or just output the panel with your success/failure message and quit.

In Textpattern 4.8.7 we’re experimenting with a way for plugins to add custom steps directly to the panels. Unfortunately for you in this instance, it’s only live on the Users and Diagnostics panels, but if it works well enough (and it’s looking good so far) we’ll roll it out to other panels. Doesn’t help you now, but just a heads-up that this functionality is slated and will then mean you don’t need to do the pre=1 dance.


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

Board footer

Powered by FluxBB