Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#49 2014-12-13 22:22:13

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

Re: Making plugins first-class citizens

ruud wrote #286483:

Brilliant work and exciting results, but strange question :)

In these examples, the difference is less than 1 millisecond. Which makes me wonder if this is worth doing at all (although it’s certainly fun trying).

Of course it’s worth doing, and wherever possible. Here is a “real-life” example (monthly archive) where you win ~0.1s (~40%) for ~250 articles:

<txp:article_custom wraptag="ul" sort="Posted ASC" limit="9999">
	<txp:variable name="year" value='<txp:if_different><txp:posted format="%Y" /></txp:if_different>' />
	<txp:variable name="month" value='<txp:if_different><txp:posted format="%Y-%b" /></txp:if_different>' />
	<txp:if_first_article>
		<li><txp:posted format="%Y" /><ul>
		<li><txp:posted format="%b" /><ul>
	<txp:else />
		<txp:if_variable name="month" value=""><txp:else />
			</ul></li>
			<txp:if_variable name="year" value=""><txp:else />
				</ul></li>
				<li><txp:posted format="%Y" /><ul>
			</txp:if_variable>
			<li><txp:posted format="%b" /><ul>
		</txp:if_variable>
	</txp:if_first_article>
	<li class="article"><txp:permlink><txp:title /></txp:permlink></li>
	<txp:if_last_article>
		</ul></li></ul></li>
	</txp:if_last_article>
</txp:article_custom>

Offline

#50 2014-12-14 09:09:58

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

Re: Making plugins first-class citizens

ruud wrote #286482:

One thing that may be interesting to try is to cache the $stack contents in a database. That way you don’t just benefit on loops, but also on repeated requests of the same page.

This could even be partly (e.g. pages and forms) done admin-size, so fetch_form() would retrieve the fully parsed form tree. No additional db query is required this way.

Offline

#51 2014-12-14 12:48:44

ruud
Developer Emeritus
From: a galaxy far far away
Registered: 2006-06-04
Posts: 5,068
Website

Re: Making plugins first-class citizens

etc wrote #286509:

This could even be partly (e.g. pages and forms) done admin-size, so fetch_form() would retrieve the fully parsed form tree. No additional db query is required this way.

You could even skip loading the actual form/page contents and just pass the sha1 hash as an argument to the parse() call (except in <txp:php> constructs that contain TXP tags) and save a few more microseconds (around 10% speed increase). And while we’re at it, also store the existence and location of the else tag, which would speed it up even further.

By parsing the moment you save/edit a page/form, you could additionally warn the user about parsing errors, thus avoiding non-functional websites to some degree. This is something that can be done with the current parser as well. In that case you’d want an additional, more strict parser that warns about improper tag nesting and missing closing tags.

Having said that, using a caching plugin is a far more effective solution for some problems, like long article lists.

Offline

#52 2014-12-14 20:47:39

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

Re: Making plugins first-class citizens

This is getting serious… I like it, thanks!

Although possibly off-topic (ignore if so), would all this talk of cacheing and hashing give us the ability to bypass the forced linear nature of pages to avoid logic errors? An example that springs to mind is trying to use the navigation tags older/newer before a call to <txp:article />, which results in no navigation links. Or trying to use the search results before calling an article.

The current antidote of course, is to include a pgonly article tag before the nav elements. But it’s a trifle annoying, because you have to remember to update both tags and use identical attributes in both places or things get weird.

I don’t know if the current parser is able to recognise the fact it’s seen a pgonly article already and thus bypass the second call to the database, or if it makes two calls for the same content, albeit the first one short-circuits prior to completion. I suspect it makes two calls, but have never really delved into it in great detail.

Being able to effectively ‘defer’ processing of dependent tags until after the dependent content has been executed, and then replace the tags in the template with the relevant content immediately prior to page display would be terrific. Failing that, some way to minimise the round-trip impact of being forced to use two calls for the same content in some scenarios would be a step up.

As I say, might be out of scope (and I don’t know if the number of people it affects is large enough to consider, compared with the effort expended in doing it), but thought I’d throw it out there for consideration in case it was a quick win while all this parser optimisation is being bounced around.


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

#53 2014-12-14 22:14:36

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

Re: Making plugins first-class citizens

Bloke wrote #286528:

Being able to effectively ‘defer’ processing of dependent tags until after the dependent content has been executed, and then replace the tags in the template with the relevant content immediately prior to page display would be terrific. Failing that, some way to minimise the round-trip impact of being forced to use two calls for the same content in some scenarios would be a step up.

Adi has made a very smart plugin that does things like this:

<txp:adi_if_content>
	<txp:adi_if_content_insert>
		<!-- will be processed after txp:article -->
 		<txp:older/newer />
	</txp:adi_if_content_insert>
	<txp:article />
</txp:adi_if_content>

I have written a version, based on modified parse(), and can confirm that changing the processing order in the new parser is quite easy, but someone has to set this order. Should tags have kind of dependency?

Offline

#54 2014-12-15 16:37:44

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

Re: Making plugins first-class citizens

ruud wrote #286516:

And while we’re at it, also store the existence and location of the else tag, which would speed it up even further.

And why not store both parsed true/false parts?

Having said that, using a caching plugin is a far more effective solution for some problems, like long article lists.

A clever core solution should be on txp todo list.

Offline

#55 2014-12-15 19:20:15

ruud
Developer Emeritus
From: a galaxy far far away
Registered: 2006-06-04
Posts: 5,068
Website

Re: Making plugins first-class citizens

etc wrote #286578:

And why not store both parsed true/false parts?

Because those are already stored in $stack when you parse the entire tree instead of just the current level. The only thing parseElse needs to know is if/where the <txp:else/> tag is in $stack[$hash][$level]

Offline

#56 2014-12-15 20:13:35

ruud
Developer Emeritus
From: a galaxy far far away
Registered: 2006-06-04
Posts: 5,068
Website

Re: Making plugins first-class citizens

Bloke wrote #286528:

Although possibly off-topic (ignore if so), would all this talk of cacheing and hashing give us the ability to bypass the forced linear nature of pages to avoid logic errors? An example that springs to mind is trying to use the navigation tags older/newer before a call to <txp:article />, which results in no navigation links. Or trying to use the search results before calling an article.

Can’t that be solved by returning the unparsed tag when $pretext['secondpass'] === false for tags that need defered parsing?

Offline

#57 2015-03-26 14:00:47

Destry
Member
From: Haut-Rhin
Registered: 2004-08-04
Posts: 4,909
Website

Re: Making plugins first-class citizens

I’m reading this wonderful, gentlemanly (so far) thread about something I see full value in from a user standpoint (ease of reading template markup), and I’m wondering why the conversation just ends ten days before Christmas. Too much eggnog?

Offline

#58 2015-03-26 15:02:07

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

Re: Making plugins first-class citizens

Destry wrote #289454:

why the conversation just ends ten days before Christmas

I simply lost track of the various patches on patches on patches, optimisations and enhancements. If someone throws a pull request or unified diff my way, I’ll test it and merge it in. This has immense value to Textpattern.


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

#59 2015-03-26 16:11:33

ruud
Developer Emeritus
From: a galaxy far far away
Registered: 2006-06-04
Posts: 5,068
Website

Re: Making plugins first-class citizens

I can prepare a patch. It would help to know which optimisations are acceptable.
I could start with the basics and perhaps then add optimisations?

Offline

#60 2015-03-26 16:38:04

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

Re: Making plugins first-class citizens

ruud wrote #289464:

I can prepare a patch. It would help to know which optimisations are acceptable.

Whichever ones you think make sense. The one that has the best performance for most situations and adds the <abc:else /> syntax, with the option of toggling short tag support on an as-needed basis would be amazing. I’m not sure from the thread so far if such a hybrid exists.

Minimising XML clashes for those that need it at the page level would be the most flexible, but I’m not sure which offers the best facilities without impacting performance. A global on/off pref is simplest, but maybe a tad granular. A preference for a whitelist of tags that remain unparsed is flexible, but not necessarily easy to maintain. Perhaps some combo might work? A global on/off pref and, I dunno, a tag that can set the short tag parsing on/off during document processing? Or a tag that can add whitelisted tag prefixes that instruct the parser to leave alone? Just shooting out ideas, not sure if any of them are viable.

I could start with the basics and perhaps then add optimisations?

If it’s not too much extra work, by all means, thank you.


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