Textpattern CMS support forum

You are not logged in. Register | Login | Help

#11 2014-11-17 18:15:00

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 #285840:

Superb, thanks. Hadn’t considered EvalElse() but from reading the patch, it seems to allow lovely constructs like: […] effectively retrofitting every plugin with a personal else tag.

Hmm… to do that you’d have to replace

$els = strpos($thing, '<txp:else');

with something monstrous like (not tested):

for ($pos = 3, $len = strlen($thing); $pos < $len and false !== $pos = strpos($thing, ':else', $pos+1);)
{
  if ($thing[$pos - 4] != '<') continue;
  for ($i = $pos - 3; $i < $pos; $i++) if (ord($thing[$i]) < 97 or ord($thing[$i]) > 122) continue 2;
  $len = true;
}
$pos = $len ? $pos : $false;

but if we’re not desperately trying to avoid preg_match, you could replace:

$els = strpos($thing, '<txp:else');

if ($els === false) {
    // no <txp:else /> tag
    if ($condition) { 
        return $thing;
    }

    return '';
} elseif ($els === strpos($thing, '<') or $els + 4 === strpos($thing, ':') or !preg_match('/<[a-z]{3}:/', substr($thing, 0, $els))) {
    // no TXP tag before the <txp:else /> tag
    if ($condition) {
        return substr($thing, 0, $els);
    }

    return substr($thing, strpos($thing, '>', $els) + 1);
}

with (also not tested):

if (false === $els = strpos($thing, ':else', 4) or !preg_match('/<[a-z]{3}:(\w+)/', $thing, $matches)) {
    // no <txp:else /> tag
    if ($condition) {
        return $thing;
    } else {
        return '';
    }
} elseif ($matches[1] === 'else') {
    // <txp:else /> is the first tag in $thing
    if ($condition) {
         return substr($thing, 0, $els - 4);
    } else {
         return substr($thing, strpos($thing, '>', $els) + 1);
    }
}

Keep in mind, that this part of the code is just speed optimisation. If someone passes <txp:title /> :else that ideally would trigger the “no <txp:else />” condition, but failing to do so doesn’t break EvalElse. It just makes it a bit slower. Realistically, that is not a situation that will occur a lot. If $thing contains :else, then it’s very likely that it’s part of a TXP tag.

Offline

#12 2014-11-17 19:46:56

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 8,611
Website

Re: Making plugins first-class citizens

No worries if it doesn’t do that. I just read the code wrong in haste. Speed of parsing is my main concern rather than the bonus of a mega else tag so the original patch with the EvalElse fixes is just fine at the mo. Thanks for your hard work.


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

#13 2014-11-17 20:29:23

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

Re: Making plugins first-class citizens

I don’t think it’ll matter much as far as parsing speed is concerned. That last rewrite with the mega else tag may even be faster than the earlier version I posted. I’d have to test to make sure, because you’d be trading multiple strpos() calls for executing a preg_match() more often.

Offline

#14 2014-11-17 20:30:29

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 8,611
Website

Re: Making plugins first-class citizens

ruud wrote #285847:

That last rewrite with the mega else tag may even be faster than the earlier version I posted.

Well in that case, it might be worth a shot!


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

#15 2014-11-17 21:25:31

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

Re: Making plugins first-class citizens

Simple benchmark with 6 test strings:
$thing = ‘some very long text that does not contain an else tag’;
$thing = ‘<txp:else />some very long text that does contain an else tag’;
$thing = ‘some very long text that does contain an else tag… but no other tags<txp:else />’;
$thing = ‘some <b>very long</b> text: that does contain an else tag and other tag <txp:else />’;
$thing = ‘some very long text that does contain an else tag and <txp:other /> tag <txp:else />’;
$thing = ‘<txp:other />some very long text that does contain an else tag and other tag <txp:else />’;

Running that through EvalElse 250.000 times for the above strings gives these results (in seconds):

---
	0.1563	0.1600	0.1795
	0.3106	0.3191	0.6979
	0.3170	0.3202	0.7330
	0.3231	0.7217	0.7891
	1.8087	2.2145	2.2133
	1.8040	2.1788	2.1954

First column: current TXP version
Second column: parsing tags with a 3-char prefix, but with just <txp:else />
Third column: parsing tags with a 3-char prefix, including Stef’s mega else tag.

The impact here is at most 0.4 seconds per 250.000 iterations, which is nothing compared to total page load time. I’d trade that for being able to write templates that are more easy to read.

Offline

#16 2014-11-17 21:51:22

gomedia
Plugin Author
Registered: 2008-06-01
Posts: 1,225
Website

Re: Making plugins first-class citizens

ruud wrote #285853:

I’d trade that for being able to write templates that are more easy to read.

Hear, hear … one of Textpattern’s great strengths.

Offline

#17 2014-11-17 22:47:47

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

Re: Making plugins first-class citizens

gomedia wrote #285854:

Hear, hear … one of Textpattern’s great strengths.

Which is one of the main reasons I was attracted to Textpattern and why I am still here.


Michael K. Pate | Pate Technologies

Offline

#18 2014-11-18 11:46:16

etc
Developer
Registered: 2010-11-11
Posts: 3,106
Website

Re: Making plugins first-class citizens

Guys, I hope you know what you are doing. There are many common 3-letters xml namespaces (rdf, owl, geo, …). By registering some geo_plugin, you are seriously compromising the possibility to export an article (with, say, rah_eo) as

xml
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
  <geo:Point>
    <geo:lat><txp:custom_field name="lat" /></geo:lat>
    <geo:long><txp:custom_field name="long" /></geo:long>
  </geo:Point>
</rdf:RDF>

Provide at least the possibility to “unregister” some namespaces in parse(), etc. We can still call <txp:geo_lat /> if needed.

Please get me right, I like the idea, but life is life.


etc_[ query | search | pagination | date | tree | cache ]

Offline

#19 2014-11-18 12:48:36

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

Re: Making plugins first-class citizens

When registering tags it’s possible to collect a list of used prefixes and only allow only those to be parsed. You’d still get into problems with a plugin that registers the “geo” prefix combined with those <geo:lat> tags.

In addition to that, we could limit this new prefix stuff to tags that are registered. That should motivate plugin authors to update their plugins ;)

Offline

#20 2014-11-18 12:59:40

etc
Developer
Registered: 2010-11-11
Posts: 3,106
Website

Re: Making plugins first-class citizens

ruud wrote #285888:

You’d still get into problems with a plugin that registers the “geo” prefix combined with those <geo:lat> tags.

That’s what I say too. An opt-out entry in Preferences, maybe?


etc_[ query | search | pagination | date | tree | cache ]

Offline

Board footer

Powered by FluxBB