Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#16 2014-09-19 14:58:56

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

Re: Custom theme options

Bloke wrote #283888:

I thought I’d just give you a taste of what you will be able to do at some point in future.

Stef, are you talking’bout Paradise? :) If you need a guinea pig, count me in.

Meanwhile, with a bit of code duplication (txp if awfully unmodular sometimes), I have written this small plugin, testers welcome.

Last edited by etc (2014-09-22 14:31:41)

Offline

#17 2014-09-19 18:22:24

michaelkpate
Moderator
From: Avon Park, FL
Registered: 2004-02-24
Posts: 1,379
Website GitHub Mastodon

Re: Custom theme options

etc wrote #283899:

I have written this small plugin, testers welcome.

I used smd_prefalizer to make a new Preference named Dog and I never could get it to appear. When I tried to edit it to lowercase that never seemed to take. So I deleted that one and made a new one named doggy – yesnoradio type.

<meta name="Fido" content="<txp:variable name="site_color" />:

<txp:if_variable name="doggy" >
Bow WoW Wow
<txp:else />
No Dogs Allowed
</txp:if_variable>

">

And this is the Output:

<meta name="Fido" content="#FABC2B:


Bow WoW Wow


">

So it works great if you use it correctly.

Offline

#18 2014-09-19 19:26:16

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 12,440
Website GitHub

Re: Custom theme options

etc wrote #283899:

Stef, are you talking’bout Paradise? :) If you need a guinea pig, count me in.

Hehe, it’s not quite paradise yet. Rather OT, but at the moment you can do this kind of thing in 4.6.0+:

// Register plugin prefs with Preferences panel and assign privs.
add_privs('prefs.abc_my_plug', '1,2,3,4');
register_callback('abc_my_plug_prefs', 'prefs', '', 1);

// Install prefs if they don't already exist.
// Called when the Preferences panel is visited.
function abc_my_plug_prefs($evt, $stp)
{
	$myprefs = abc_my_plug_get_prefs();

	foreach ($myprefs as $key => $prefobj) {
		if (get_pref($key) === '') {
			set_pref(
				$key,
				doSlash($prefobj['default']),
				'abc_my_plug',
				$prefobj['type'],
				$prefobj['html'],
				$prefobj['position'],
				$prefobj['visibility']
			);
		}
	}
}

// Custom widget renderer for a select list.
function abc_my_plug_list($key, $val)
{
	$myprefs = abc_my_plug_get_prefs();
	$obj = $myprefs[$key];

	return selectInput($key, $obj['content'], $val);
}

// List of preferences in the plugin as an array.
// Each entry contains everything there is to know about each pref.
// The key is the entry as it appears in the txp_prefs table. Passed thru gTxt() prior to rendering.
// The other entries are mostly for set_pref()'s benefit. See abc_my_plug_prefs() for installation.
function acb_my_plug_get_prefs()
{
	$abc_my_plug_prefs = array(
		'abc_my_plug_opt_in' => array(
			'html'       => 'yesnoradio',
			'type'       => PREF_PLUGIN,
			'position'   => 30,
			'default'    => '0',
			'visibility' => PREF_PRIVATE,
		),
		'abc_my_plug_favourite' => array(
			'html'       => 'text_input',
			'type'       => PREF_PLUGIN,
			'position'   => 15,
			'default'    => '',
			'visibility' => PREF_PRIVATE,
		),
		'abc_my_plug_ice_cream' => array(
			'html'       => 'abc_my_plug_list',
			'type'       => PREF_PLUGIN,
			'position'   => 24,
			'content'    => array(
				'none' => gTxt('none'),
				'option_1' => gTxt('abc_my_plug_vanilla'),
				'option_2' => gTxt('abc_my_plug_mint_choc_chip'),
				'option_3' => gTxt('abc_my_plug_strawberry'),
				),
			'default'    => 'option_1',
			'visibility' => PREF_GLOBAL,
		),
	);

	return $abc_my_plug_prefs;
}

And that’s pretty much it. In this example, I’ve set up an array at the bottom that defines all the prefs I want: their id, input types, default values, visibility, content if applicable, and so forth. It’s entirely up to me.

I register the abc_my_plug_prefs() function with the Preference pane so it runs every time the panel is viewed. Note two things:

  1. The privs begin with prefs., which is a special area in Txp 4.6.0.
  2. The plugin runs ‘pre’ so it’s called before the page is rendered.

The function’s job is to just use set_pref() to install each of the prefs given in my array. Then when the page is rendered, they are included automatically under the given ‘event’ (which is run through gTxt() and forms the pref group’s heading).

There’s an example of using a custom widget renderer in there too. The html entry of the pref labelled abc_my_plug_ice_cream calls this function to render a select list of options as defined in the ‘content’ array index. Doing things this way you can very easily build prefs for the system to display without having to clone tonnes of extra markup, like you were forced to do in your plugin.

It might be even better (ummm, maybe) to have some kind of API for adding pref widgets, but this is still pretty flexible and relatively painless. Any thoughts/improvements welcome (either directly to me or discussed in another thread).


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

Hire Txp Builders – finely-crafted code, design and Txp

Online

#19 2014-09-19 20:36:58

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

Re: Custom theme options

Bloke wrote #283905:

… at the moment you can do this kind of thing in 4.6.0+: … Doing things this way you can very easily build prefs for the system to display without having to clone tonnes of extra markup, like you were forced to do in your plugin.

I’m not very fresh in the evenings, but why couldn’t we do this kind of things in 4.5? This will work, but only admins will see it, right? So the magic happens somewhere in txp_prefs.php, allowing the users with 1,2,3,4 privs to access these prefs? That sounds great, but 4.6 seems a bit far at the moment.

Actually, the code duplication is often caused by just few lines (like prefs_list(gTxt('preferences_saved')); at the end of prefs_save() function). Another example is pretext(), which should only populate $pretext array (very useful for url parsing), but it also populates article data…

Offline

#20 2014-09-19 21:55:30

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 12,440
Website GitHub

Re: Custom theme options

etc wrote #283910:

I’m not very fresh in the evenings, but why couldn’t we do this kind of things in 4.5?

You can. I have (smd_article_stats, for example). As you say, only admins see it so you need to provide a secondary mechanism for managing prefs if you want others to do so.

It’s only a small change to txp_prefs.php, but the real change is simply in admin_config.php. Instead of prefs being applied wholesale to only one group, it’s now split into sub-groups to which plugins can add. The removal of advanced prefs and consolidation of prefs into logical groups helps massively too. The Languages panel and lack of suitable markup got in the way of doing it on 4.5.

Actually, the code duplication is often caused by just few lines (like prefs_list(gTxt('preferences_saved')); at the end of prefs_save() function). Another example is pretext(), which should only populate $pretext array (very useful for url parsing), but it also populates article data…

If you have better mechanisms for these areas, then by all means share them / submit a patch. Would love to make it better for plugins to have to duplicate less code.


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

Hire Txp Builders – finely-crafted code, design and Txp

Online

#21 2014-09-19 22:17:11

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

Re: Custom theme options

Just splitting prefs_save() in txp_prefs.php would avoid (me) duplicating it:

	/*** new function that just saves preferences ***/

	function save_prefs($where = 'prefs_id = 1')
	{
		global $prefs, $gmtoffset, $is_dst, $auto_dst, $timezone_key;

		$prefnames = safe_column("name", "txp_prefs", $where);

		$post = doSlash(stripPost());

		// Forge $auto_dst for (in-)capable servers
		if (!timezone::is_supported())
		{
			$post['auto_dst'] = false;
		}
		$prefs['auto_dst'] = $auto_dst = $post['auto_dst'];

		if (!$post['auto_dst'])
		{
			$is_dst = $post['is_dst'];
		}

		// Forge $gmtoffset and $is_dst from $timezone_key if present
		if (isset($post['timezone_key']))
		{
			$key = $post['timezone_key'];
			$tz = new timezone;
			$tzd = $tz->details();
			if (isset($tzd[$key]))
			{
				$prefs['timezone_key'] = $timezone_key = $key;
				$post['gmtoffset'] = $prefs['gmtoffset'] = $gmtoffset = $tzd[$key]['offset'];
				$post['is_dst'] = $prefs['is_dst'] = $is_dst = timezone::is_dst(time(), $key);
			}

		}

		foreach($prefnames as $prefname) {
			if (isset($post[$prefname])) {
				if ($prefname == 'siteurl')
				{
					$post[$prefname] = str_replace("http://",'',$post[$prefname]);
					$post[$prefname] = rtrim($post[$prefname],"/ ");
				}

				safe_update(
					"txp_prefs",
					"val = '".$post[$prefname]."'",
					"name = '".doSlash($prefname)."' and $where"
				);
			}
		}
	}

	/*** the good old prefs_save() ***/

	function prefs_save()
	{
		save_prefs();
		update_lastmod();
		prefs_list(gTxt('preferences_saved'));
	}

Offline

#22 2014-09-19 23:47:00

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 12,440
Website GitHub

Re: Custom theme options

etc wrote #283914:

Just splitting prefs_save() in txp_prefs.php would avoid (me) duplicating it:

Interesting. Presumably the same would have to be done for advanced prefs, at least for now until they disappear in 4.6. The only thing that stops me from doing that kind of construct is that once we’ve ‘exposed’ the function and plugins rely on it, it becomes difficult to change in future. If you compare how 4.5.x and 4.6.x save prefs you’ll see the potential issue.

On the surface it looks like doing something similar in 4.6 would work. i.e. removing the bulk of the processing to the save_prefs() function and leaving just the output stuff in prefs_save(). But the queries change fairly significantly between versions because there’s more privs checking done in saves under 4.6, as well as the fact the two types of pref are consolidated. That’s a backwards-incompatible change with your proposal, as far as I can see.

In addition, the custom field portion of save_prefs() is going to disappear soon, and there are a lot of exceptions in there that simply don’t apply to plugins, but which plugins might come to rely upon if they could call the function.

I think this kind of thing would be better handled with a dedicated prefs API that we can compartmentalize. Split the save process a little further, perhaps even keep the core exception processing external to the “public” save function, which maybe takes the posted values and/or where clause as parameters.

Or perhaps better is to trigger prefs.prepare and prefs.saved callbacks, to which the core can subscribe to do its pre-processing of the posted values. Plugins can then also hook into them if required or call just the ‘save’ function, which is then shielded from all the exceptions and tomfoolery with name/value pairs prior to save.

Dunno, just thinking out loud. I might be wrong. Feel free to correct me if I’m missing something.


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

Hire Txp Builders – finely-crafted code, design and Txp

Online

#23 2014-09-20 08:56:27

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

Re: Custom theme options

Bloke wrote #283915:

The only thing that stops me from doing that kind of construct is that once we’ve ‘exposed’ the function and plugins rely on it, it becomes difficult to change in future. … the queries change fairly significantly between versions because there’s more privs checking done in saves under 4.6, as well as the fact the two types of pref are consolidated. That’s a backwards-incompatible change with your proposal, as far as I can see.

That’s true, but with all these changes, my custom save function in the plugin above will be 4.6 incompatible anyway. IMO, mapping depreciated functions to something new in the core is easier than rewriting every plugin.

I think this kind of thing would be better handled with a dedicated prefs API that we can compartmentalize. Split the save process a little further, perhaps even keep the core exception processing external to the “public” save function, which maybe takes the posted values and/or where clause as parameters.

Exactly! Separate data retrieval/preparing/processing/output as much as possible (so it would be save_prefs($where = 'prefs_id = 1', $post = stripPost())). I dunno what is the best way, prefer to leave it with you. :)

Offline

#24 2014-09-20 21:18:59

gfdesign
Member
From: Argentina
Registered: 2009-04-20
Posts: 401

Re: Custom theme options

etc wrote #283899:

Meanwhile, with a bit of code duplication (txp if awfully unmodular sometimes), I have written this small plugin, testers welcome.

Very well, guys!. It’s something goes towards what I’d like. (Not even I didn’t know about ‘smd_prefalizer’ plugin. Very interesting!). In case someday it becomes in a polished plugin, don’t forget to include others kind of input fields and their corresponding description in order to the user knows what is filling. As you all can see, I am talking / asking from the final user because I have no enough knowledge about programming therefore you’ll have to excuse me. :D
Many thanks for invest time in this.

Offline

#25 2014-09-21 13:55:44

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

Re: Custom theme options

gfdesign wrote #283957:

In case someday it becomes in a polished plugin, don’t forget to include others kind of input fields and their corresponding description in order to the user knows what is filling.

Whether it becomes polished, mainly depends on you (and other users), I don’t know what kind of input fields you need. You (site admin) can already create multiple text, yes/no, on/off, color variables, and give them any description, as explained in the plugins… well… help.

Offline

#26 2014-09-22 04:53:34

gfdesign
Member
From: Argentina
Registered: 2009-04-20
Posts: 401

Re: Custom theme options

etc wrote #283975:

Whether it becomes polished, mainly depends on you (and other users), I don’t know what kind of input fields you need. You (site admin) can already create multiple text, yes/no, on/off, color variables, and give them any description, as explained in the plugins… well… help.

Sorry Oleg, but I didn’t found how to put a name and descripción to the options I’ve created but let’s suppose, I want to create a variable to put an Analytic Google code to my site. This option would be called “Google Analytics”, its variable ‘google_analytics’ and the description indicating “Please insert here your Google Analytics code”. So, basically we’ll need to indicate:
  • Option name: ‘Google Analytics’
  • Variable name: google_analytics
  • Type of field (in this case should be a textarea, don’t you?)
  • Description (to give to the user some instructions about it)
  • Order or position (it would be great if it could be defined through a drag n’ drop feature)
  • Public (as adi_variable puglin brings)
  • Category or group which it belongs
  • Required or not
  • (Anything else?)
Other example, could be give to the client the availability to add some static text for the footer of his/her site. Therefore we’ll have:
  • Option name: ‘Text for Footer’
  • Variable name: text_footer
  • Type of field (I guess, in this case could be a textarea using a WYSWYG editor)
  • Description (to give to the user some instructions about it)
  • Order or position
  • Public
  • Category or group which it belongs
In Wordpress you can use Advanced Custom Field plugin and create some fields for your content, even an Option Page (such as I’d like for Txp). In summary, this plugin brings with some fields as I put below:
  • Text: Single line text field, optional HTML support, character limit
  • Text Area: Multi-line text field, optional HTML support, character limit
  • Number: Number, min/max values
  • Email: Validates email input
  • Password: Masks text for password input
  • Wysiwyg Editor: Optional WP media insertion, basic/full editor buttons
  • Image: Upload image or select from WP library, returns object, url or ID
  • File: Upload file or select from WP library, returns object, url or ID
  • Select: Provide options in drop-down, supports multi-select
  • Checkbox: Allow selection of multiple items in checkbox list
  • Radio Button: Allow selection of single item from radio button list
  • True / False: Simple true / false selector
  • Page Link: Returns URL of any post or page, can be limited to specific post types
  • Post Object: Returns WP object of any post or page, can be limited to specific post types or taxonomies
  • Relationship: Same as post object, but with improved interface and drag-drop reordering
  • Taxonomy: Returns object or ID for one or more taxonomy terms, can be limited to tags, categories or custom taxonomies
  • User: Select one or more users, can be limited by role
  • Google Map: Set lat/long center, zoom level, and width
  • Date Picker: Select calendar date, return formatted date string
  • Color Picker: Select hexadecimal color
  • Message: No options, leave a message for users
  • Tab: Collect following fields into a tab interface.

I don’t pretend all of them fields in a plugin, but I’d like to see some similar in TXP since I guess it would be very handy for many TXP users :)

Offline

#27 2014-09-22 08:34:32

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

Re: Custom theme options

I see better now, thank you, Fernando. The WP plugin looks great, but it’s a big piece of code. Given the forthcoming 4.6-changes, it’s risky to invest much efforts into something potentially incompatible. But the basic functionality could be quickly implemented. Let’s take your example (in smd_prefalizer):

  • Option name: ‘Google Analytics’: these are localized in txp_lang table, let’s pray Stef to add a field or two to smd_prefalizer :)
  • Variable name: google_analytics: that’s ok
  • Type of field (in this case should be a textarea, don’t you?): longtext_input in txp. We could plug some wysiwyg editor in. * Order or position (it would be great if it could be defined through a drag n’ drop feature): ok, d’n‘d why not.
  • Public (as adi_variable puglin brings): what does it mean? Once created, <txp:variable /> is accessible to everyone.
  • Category or group which it belongs: could be grouped in something like variable-design, variable-options etc. What for?
  • Description (to give to the user some instructions about it), Required or not: this is a bit less straightforward, txp_prefs has not enough fields to store data. Probably, adding a general-purpose data field could help. For example, if the input_control is a select box, this field could contain a description, plus select1: Google, select2: Yahoo, ..., maybe json-encoded. But again, 4.6-compatibility? We could also store it in a separate table.

I’ll experiment with it and report back.

Offline

#28 2014-09-22 09:38:02

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 12,440
Website GitHub

Re: Custom theme options

gfdesign wrote #284008:

I didn’t found how to put a name and descripción to the options I’ve created

I haven’t looked at etc’s code but the way to probably do this is via Textpack language strings. We could do with a string editor plugin being created, similar to smd_prefalizer in concept (but better executed!) specifically for managing language strings.

Descriptions of fields are covered by help topics. A better system for allowing plugins to define those is being worked out: they are essentially language strings. At the moment, such strings come only from the RPC server, which is a constraint, but the core help topics have been migrated to Github in preparation for bundling them with a core distribution at some point.

Other example, could be give to the client the availability to add some static text for the footer of his/her site.

Hmmm, this I’m not so sure about. While the new custom fields feature will address a large portion of your meta data needs out of the box, for blocks of content like footer text, it’s less useful.

Why not use either a Form to hold the text (which you pull into your templates at the correct location via <txp:output_form form="footer_text" />) or use the Write panel to compose text in a special Section that you never display articles from? The latter allows you to employ WYSIWYG plugins and there are probably plugins out there that can limit the panel’s content for certain Sections. Umm, maybe, if they still work.

There’s nothing to stop a clever plugin operating like adi_matrix for Forms, allowing you to use them as true snippet holders without all the other interface clutter. So you could give admins access to this stripped-down, sanitized area that only showed Forms of maybe one type (like ‘Section’ or ‘Misc’ or something). In there, people could just write content which would get folded into the site’s templates.

Footer content isn’t custom meta data, as such. It’s more presentational than data- or content-driven and usually doesn’t vary that much from page to page. That said, plans are afoot to embed custom fields against Sections so you could conceivably do this kind of thing, but it would get annoying pretty quickly if you had a lot of Sections to have to paste the same content in the field for every Section: a reusable Form is a much better place for this than a per-Section field, imo.

Going back to the footer example, I don’t see why you’d need an order/position field. The position is always “the footer” isn’t it? You don’t stack content do you? A need for Category is questionable. And as for ‘Public’… erm? What have I missed here about the design process? Everything’s public, right?

Regarding the list of field types you gave, there are some interesting ones there. I haven’t thought about File/Image upload directly baked into core custom fields, nor colour pickers or user lists or any of the other esoteric ‘aggregate’ types. But since the system is designed to be extensible, there’s no reason a short plugin couldn’t add them as a new ‘type’. Same with Geo location: you can either add four or five fields yourself, or a tiny plugin could add them for you as a set.

Some interesting ideas there, though. We’ll consider them as development presses on.


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

Hire Txp Builders – finely-crafted code, design and Txp

Online

#29 2014-09-22 11:20:20

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

Re: Custom theme options

Bloke wrote #284030:

I haven’t looked at etc’s code…

Globally sane attitude, but the code is manly copy/pasted from txp_prefs.php in this case (as promptly complained few posts above)

…but the way to probably do this is via Textpack language strings.We could do with a string editor plugin being created, similar to smd_prefalizer in concept (but better executed!) specifically for managing language strings.

Wouldn’t it be loverly if you could integrate txp_lang.data field into smd_prefalizer interface (with save/delete)?

Offline

#30 2014-09-22 12:15:01

philwareham
Core designer
From: Haslemere, Surrey, UK
Registered: 2009-06-11
Posts: 3,565
Website GitHub Mastodon

Re: Custom theme options

Bloke wrote #284030:

Regarding the list of field types you gave, there are some interesting ones there. I haven’t thought about File/Image upload directly baked into core custom fields, nor colour pickers or user lists or any of the other esoteric ‘aggregate’ types. But since the system is designed to be extensible, there’s no reason a short plugin couldn’t add them as a new ‘type’.

Also remember we have support for jQuery UI in 4.6, so things like datepickers would be fairly easy to incorporate I hope. I’m sprinkling a few jQuery UI bits into my changes to the UI at the moment. Some of the other input types such as input type=color could handle colour pickers if/when all the major browsers fully support HTML5 input types. Just a thought.

Offline

Board footer

Powered by FluxBB