Textpattern CMS support forum
You are not logged in. Register | Login | Help
- Topics: Active | Unanswered
#1 2010-04-14 14:30:11
- jeadorf
- Plugin Author
- From: München, DE
- Registered: 2010-04-13
- Posts: 12
The obvious way of adding preferences to one's plugin
Hello,
I am trying to add several preferences to a syntax highlighting plugin in order to allow users to customize line numbers, style and so on.
Does anyone have a clue how this is done (in general), or even better, know one of the existing
plugins that uses a lot of preferences?
These are the possibilities that I’ve found so far:
- hak_tinymce – shows a self-made solution using an extra database table.
- Setting plugin flag PLUGIN_HAS_PREFS enables an ‘Option’ link below ‘Edit’ and ‘Help’ in the plugins tab. This link opens up an option tab that seems to be the right place to add a lot of form elements.
- It might be possible to copy the solution from textpattern/txp_prefs.php yet this causes a lot of duplication and looks like a really nasty hack to me
- there is soo_plugin_pref which might provide a solution. But that would mean (?) another requirement for all plugins that want to use preferences?
- hacking the plugin’s code to insert one’s preferences (an absolute NO-GO)
- hooking into the admin preferences tab of Textpattern and add preferences to the existing list (see set_pref and table txp_prefs). This is my current solution. It does not exacty seem the right way though.
Thank you for any hints, ideas or plugin that already shows a solution to this problem!
Last edited by jeadorf (2010-04-14 14:30:43)
Offline
Re: The obvious way of adding preferences to one's plugin
jeadorf wrote:
there is soo_plugin_pref which might provide a solution. But that would mean (?) another requirement for all plugins that want to use preferences?
Yes, if you use soo_plugin_pref
then users would have to install that too to be able to manage your plugin’s preferences. However, it would make your life easier :)
Code is topiary
Offline
Re: The obvious way of adding preferences to one's plugin
Option #2 is the best native approach. The section on Plugin Callbacks in the wiki gives a bit more info. Once the callback fires and you’re on that tab you can render your widgets however you see fit. Check lib/txplib_form.php
and lib/txplib_html.php
for some helper functions for building UI elements.
The downside to that approach is that you’ll still need to register a tab/callback/step for your plugin’s save routine which will call set_pref()
to store the user’s choices; probably using PREF_HIDDEN
and PREF_PRIVATE
so it makes some hidden (from the Prefs tab) per-user preferences.
Although not a simple plugin, ied_plugin_composer does that with its prefs so you could study the top few functions there to see how it hangs together. A couple of my admin-side plugins do the same kind of thing; smd_tags and smd_admin_themes spring to mind. For an excellent example of mingling a plugin pref among the Advanced Prefs pane, see rvm_css.
Or, as jsoo says, save yourself the hassle and use his plugin :-)
btw, if you’re delving into prefs territory another useful companion plugin is smd_prefalizer to help you check, set and play about with any prefs you create.
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
#4 2010-04-15 01:23:05
- jeadorf
- Plugin Author
- From: München, DE
- Registered: 2010-04-13
- Posts: 12
Re: The obvious way of adding preferences to one's plugin
Thank you very much! The ied_plugin_composer plugin was a good sample in combination with the soo_plugin_pref manual.
I implemented the following solution:- using the option panel (required plugin type set to admin+client, see ied_plugin_composer to decode magic numbers)
- using soo_plugin_pref (works like a charm!) as an optional requirement
Offline
#5 2011-01-12 02:04:52
- ~cXc~
- Plugin Author
- Registered: 2010-12-27
- Posts: 39
Re: The obvious way of adding preferences to one's plugin
I’m trying to add prefs[‘cxc’] stuff to a plugin and trying to make sure I’m doing it right, I haven’t been able to figure this out and this seems to be a question much like the ones I would ask … but I don’t quite follow the solution or what you ended up doing. I’ve posted all the code I’m using to add my prefs[‘cxc’] at the moment below the first block is called on initial plugin access only, the second block is part if the import/install and changes the database entry … this is automatic and there is never any interaction between the user, if it matters cxc_templates is the name of my plugin thats why my pref[‘cxc’] is prefs[‘cxc_templates_current’] but I actually wanted to use prefs[‘cxc_tpl_current’] but reading other post and docs suggest that I use my plugin name as a prefix and I don’t want to change the name (cxc_tpl might cause misunderstandings concerning it and zem_tpl) :(
The question is have I left anything out? o.O
It does what it should but does it do it the right way?
Is there a right way?
if (!isset($prefs['cxc_templates_current']) && !safe_insert('txp_prefs', 'name = "cxc_templates_current", val = "", html = "text_input", prefs_id = 1, type = 2, event = "publish", position = 0') && !($prefs['cxc_templates_current'] = '')) {
print '
<h1 class="cxc-tpl-failure">Plugin Preferences</h1>
<ul class="results">
<li><span class="cxc-tpl-failure">Database update failed</span>update</span> entry for current template will be unavailable.</li>
</ul>
<br />
';
}
if (!safe_update('txp_prefs', 'val = "'.$dir.'"', 'name = "cxc_templates_current"')){
print '
<ul class="results">
<li><span class="cxc-tpl-failure">Unable to update</span> entry for current template in the database, '.str_replace('_', ' ', $dir).' template information will be unavailable.</li>
</ul>
<br />
';
}
I am very sorry if I misunderstood what this question asked but it sure sounds like what I need …
~cXc~
Offline
Re: The obvious way of adding preferences to one's plugin
Look in /textpattern/lib/txplib_misc.php. set_pref()
and get_pref()
will make your life a bit easier.
Always use your cxc_ prefix for anything you add to the global namespace: prefs, global variables, constants, Textpack strings, functions, & classes. You don’t have to use the full plugin name in each pref name if you don’t want — you’re the only one who has to worry about tripping yourself up with later plugins, as long as you always use your prefix. I prefer to use the full plugin name (soo_plugin_pref adds this for you, so you can deal with shorter names in the plugin code).
soo_plugin_pref is handy in that it takes care of a lot of work for you — automatically installing and deleting prefs as appropriate, and giving your plugin a simple user interface for prefs management by the user. You might get some ideas just looking over the code.
Code is topiary
Offline
#7 2011-01-12 22:57:42
- ~cXc~
- Plugin Author
- Registered: 2010-12-27
- Posts: 39
Re: The obvious way of adding preferences to one's plugin
I’ll look into set_pref() and get_pref() and see if I can figure them out thanks. I switched to cxc_tpl_current since it doesn’t matter.
Jeff please don’t take this the wrong way but using soo_plugin_pref seems much more complicated than …
if (!isset($prefs['cxc_tpl_current']) && !safe_insert('txp_prefs', 'name = "cxc_tpl_current", val = "", html = "text_input", prefs_id = 1, type = 2, event = "publish", position = 0') && !($prefs['cxc_tpl_current'] = '')) {
if (!safe_update('txp_prefs', 'val = "'.$dir.'"', 'name = "cxc_tpl_current"')){
… and the only thing that it seems to offer additionally is the removal upon uninstall. The prefs I’m setting I don’t want to be managed by the user I want them to be set automatically behind the scenes.
I wish I understood how to properly use it for my purposes but I don’t, I just want to make sure that what I’m using is an acceptable alternative. To me 2 lines of code that perform pretty much the same as 40 lines that use several functions is preferred especially for a pref maintained and updated automatically. Please understand I’m learning a lot about Textpattern and coding period as I go, you have done a great job with your documentation I just don’t understand how to use it :(
Offline
Re: The obvious way of adding preferences to one's plugin
Why set preferences if they can’t be changed by the user? What are they for?
Piwik Dashboard, Google Analytics Dashboard, Minibar, Article Image Colorpicker, Admin Datepicker, Admin Google Map, Admin Colorpicker
Offline
Re: The obvious way of adding preferences to one's plugin
soo_plugin_pref is intended for user pref management, so you’re right it is not efficient if all you want to do is put values in the prefs table. I misunderstood what you were looking for. As Matt says, if the user can’t touch them they’re not really prefs.
Code is topiary
Offline
#10 2011-01-13 00:58:15
- ~cXc~
- Plugin Author
- Registered: 2010-12-27
- Posts: 39
Re: The obvious way of adding preferences to one's plugin
Technically I suppose its not a preference, what I’m doing is storing a template name when it is installed, it will be used for displaying the last template imported and any documentation included with it. Unfortunately only the preferences table seems to provide what I need and adding an entire table to do this seems like overkill and just plain bad … o.O
Last edited by ~cXc~ (2011-01-13 01:02:03)
Offline
Re: The obvious way of adding preferences to one's plugin
You’re right, better to stash it in txp_prefs than to add a table for one piece of data. After all, Txp does much the same thing with some prefs (version #, for instance).
In your first block of code, I don’t see how the 3rd part of the conditional statement adds anything. You’ve already checked that it isn’t set, and updating the DB won’t change that.
Code is topiary
Offline
#12 2011-01-13 02:38:38
- ~cXc~
- Plugin Author
- Registered: 2010-12-27
- Posts: 39
Re: The obvious way of adding preferences to one's plugin
I’m trying to understand how set_prefs work now, are they just core functions that do the same thing as what I’ve put in my plugin?
Are the 3 if blocks the same in the following blocks?
if (!isset($prefs['cxc_tpl_current']) && !safe_insert('txp_prefs', 'name = "cxc_tpl_current", val = "", html = "text_input", prefs_id = 1, type = 2, event = "publish", position = 0') && !($prefs['cxc_tpl_current'] = '')) {
if (!isset($prefs['cxc_tpl_current']) && !set_pref('cxc_tpl_current', '', $event='publish', $type=2, $html='text_input', $position=0, $is_private=PREF_GLOBAL) && !($prefs['cxc_tpl_current'] = '')) {
if (!isset($prefs['cxc_tpl_current']) && !set_pref('cxc_tpl_current', '', $event='publish', $type=2, $html='text_input') && !($prefs['cxc_tpl_current'] = '')) {
if (!safe_update('txp_prefs', 'val = "'.$dir.'"', 'name = "cxc_tpl_current"')){
if (!set_pref('cxc_tpl_current', $dir, $event='publish', $type=2, $html='text_input', $position=0, $is_private=PREF_GLOBAL)){
if (!set_pref('cxc_tpl_current', $dir, $event='publish', $type=2, $html='text_input')){
As far as get_pref() goes do I even need it since I’m using global prefs; in the function, and I can get it much easier just using the standard $prefs[‘cxc_tpl_current’] call?
Will I need to add a remove pref option?
Should I use the set_prefs() function instead of what I’m using now?
BTW the plugin I looked at to learn how to add a pref in the first place seems to have went with the copy directly from the file you sent me looking through. What I had above was what I ended up with after I removed what I thought to be non-essential parts for creating the pref[‘cxc’] I needed. I also notice that the set_pref() is also capable of setting the user column based on the backend user so I’m thinking maybe that is something I had overlooked. Sorry for all the questions o.O but the more I understand the better I’ll do with the plugin and I’m almost finished.
[ edit ] Jeff, the third if is there because without it I get a notice when I first access the “Templates” tab since when its called later it isn’t present because it wasn’t part of the global prefs; at the time of access. Maybe this will make more sense …
Before Block 1 I call global prefs; and have the complete array
Block 1 = check to see if it exists in the current global prefs; array
Block 2 = add the cxc_tpl_current entry to the database
Block 3 = sets the current array to include pref[‘cxc_tpl_current’] so I don’t have to call global prefs; again [ /edit ]
[ edit ] It seems the first 3 blocks above are the same and the last 3 blocks are the same since adding the 3 block of each example above did the same thing as the first block of each area :)
… still doesn’t update the user column though o.O [ /edit ]
Last edited by ~cXc~ (2011-01-13 10:12:30)
Offline