Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#13 2014-09-18 15:35:51

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

Re: Custom theme options

Hola Fernando,

I think it would be logical to integrate these options into Preferences tab. Give me an example of what you need, and I’ll try to work something out.

Offline

#14 2014-09-19 03:16:03

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

Re: Custom theme options

etc wrote #283863:

Hola Fernando,

I think it would be logical to integrate these options into Preferences tab. Give me an example of what you need, and I’ll try to work something out.

Hi Oleg.
Thanks for your reply. As lucass asked / showed at the beginning of this topic, I’ve also worked with some projects in Wordpress and it seemed me interesting the idea that user has the capability to change some values of his/her site. However, I wouldn’t put these options under Preferences because I think over there are technical options rather than options related to design of the site therefore only we as super admins should have access.

In others words, I would like be able to offer a website where the clients can change some stuff such as the logo, slogans, email contact, number of articles will show in the home, color or image of background, links to their social networks, some statics texts, the favicon, and so on. Probably ‘Theme options” is not the most accurate name inside of Textpattern. Maybe an appropriate name for this new tab could be ‘General setting’ or something.

For example, in Wordpress with the help of some plugins or frameworks, the superadmin can create an options page with a lot of fields along with their descriptions in order to be filled by the user than later they will be used in the pages of the site.

I hope the idea has been clear :D
Best regards

Offline

#15 2014-09-19 10:18:25

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

Re: Custom theme options

gfdesign wrote #283870:

However, I wouldn’t put these options under Preferences because I think over there are technical options rather than options related to design of the site therefore only we as super admins should have access.

Currently this is true: the preferences panel is unavailable to anybody below Managing Editor. From 4.6.0, this changes. The Prefs panel is going to be open to everybody, but only Managing Editors and above can see the Txp prefs.

This subtle change offers more granularity and better control over preferences. For instance, if you wanted to open up just the Comments prefs area to certain groups of people, you alter the prefs.comments privilege.

This also opens up the Prefs panel to plugin authors, offering fine-grained control over their prefs. They just register their plugin with the built-in prefs hook or their own callback, add the prefs to the database, then when appropriate privs are set, the prefs will appear on the panel for those groups.

Combined with this, unlimited custom fields smattered across the interface will allow you to collect and output arbitrary meta data. For example, adding meta fields to Users would allow you to collect additional user data like website, twitter links, etc, like smd_bio does. You’d still have the issues that only an admin can set these values, though, unless a plugin (like smd_bio) overrides this behaviour, so you might be better to collect these on a separate panel, such as Prefs. You can then output these in varying ways in your templates using the <txp:custom_field > tag.

None of this helps you right now of course, but I thought I’d just give you a taste of what you will be able to do at some point in future.


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

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

etc
Developer
Registered: 2010-11-11
Posts: 5,053
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: 11,271
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.

Txp Builders – finely-crafted code, design and Txp

Offline

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

etc
Developer
Registered: 2010-11-11
Posts: 5,053
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: 11,271
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.

Txp Builders – finely-crafted code, design and Txp

Offline

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

etc
Developer
Registered: 2010-11-11
Posts: 5,053
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: 11,271
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.

Txp Builders – finely-crafted code, design and Txp

Offline

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

etc
Developer
Registered: 2010-11-11
Posts: 5,053
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

Board footer

Powered by FluxBB