XH 1.7: sprint #6

Discussions and requests related to new CMSimple features, plugins, templates etc. and how to develop.
Please don't ask for support at this forums!
cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

XH 1.7: sprint #6

Post by cmb » Sun Apr 02, 2017 10:59 pm

Hi everybody!

I have opened the voting on 55 tickets.

Please preferably vote by adding your reaction where it is not misunderstandable (e.g. add +1/-1 to my comment where I suggested to do something), or by adding a short comment (longer discussions might better done in the respective forum thread).

Voting ends in 18 days, i.e. on April, 20th (so yeah, we'll be at least a week late for CMSimple_XH 1.7.0beta1 – not that bad!).

Thanks in advance for every vote! :)
Christoph M. Becker – Plugins for CMSimple_XH

lck
Posts: 2967
Joined: Wed Mar 23, 2011 11:43 am
Contact:

Re: XH 1.7: sprint #6

Post by lck » Mon Apr 03, 2017 12:33 pm

Always hard at work, thank you!
„Bevor du den Pfeil der Wahrheit abschießt, tauche die Spitze in Honig!“   👉 Ludwig's XH-Templates for MultiPage & OnePage

Holger
Site Admin
Posts: 3470
Joined: Mon May 19, 2008 7:10 pm
Location: Hessen, Germany

Re: XH 1.7: sprint #6

Post by Holger » Mon Apr 03, 2017 10:06 pm

Any chance to add a new hook just before cms.php fires the page? Maybe the same way as XH_afterPluginLoading()?

Background: as you maybe know I have a working solution for caching, minifying and compression of css and js files. I'll not publish it, because it requires to edit userprelude.php and this will end up with comments like "not simple" again. With a hook at the very end of cms.php it seems to become possible to buffer the complete finished html and make the whole job with a plugin.

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: XH 1.7: sprint #6

Post by cmb » Tue Apr 04, 2017 11:42 am

Holger wrote:Any chance to add a new hook just before cms.php fires the page? Maybe the same way as XH_afterPluginLoading()?
I'd welcome that. We could add a hook in XH_finalCleanUp() just before the $html gets returned. The registered callback function would receive the $html by-reference, so would be able to modify it as needed. Registering the callback could be done by a simple function for now (in the long run we should consider a more elaborate hook system, though, maybe something like hook_xh). We could call it XH_beforeOutput() – better suggestions are welcome.

PS: I've filed a respective issue.

Caveats:
  1. PHP notices etc. raised in the callback function would not be part of the debug output, so developers using such a callback should check their error_log during development.
  2. Not all requests even get to XH_finalCleanUp(); for instance Ajax-Responses usually terminate early.
Last edited by cmb on Tue Apr 04, 2017 11:49 am, edited 1 time in total.
Reason: Add PS
Christoph M. Becker – Plugins for CMSimple_XH

Holger
Site Admin
Posts: 3470
Joined: Mon May 19, 2008 7:10 pm
Location: Hessen, Germany

Re: XH 1.7: sprint #6

Post by Holger » Tue Apr 04, 2017 1:43 pm

Hmm, why inside XH_finalCleanUp() and not just at the end of cms.php :?:

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: XH 1.7: sprint #6

Post by cmb » Tue Apr 04, 2017 2:34 pm

Holger wrote:Hmm, why inside XH_finalCleanUp() and not just at the end of cms.php :?:
Hm, haven't thought about that, but it would be an option, too. In this case manipulating several of the global variables would be easy, but as the template has already been included, it might not make much sense to do so. Accessing the so far generated HTML would also be easy, but to modify it one would have to fiddle with PHP's output buffering – not necessarily hard, but somewhat error prone.

Yet another option would be to add a hook just before the template is included, or maybe even before the output buffering is started.

Anyhow, with regard to minification of CSS and JS, an enqueue system (perhaps just two functions: one for linking of stylesheets, and one for inclusion of JS files, similar to ::addScript() and ::addStylesheet()) might simplify things (no need to parse <link> and <script> elements), and we could integrate the minification code into the core in the first place. Plugins not yet using these functions would get no minification, but that might encourage plugin authors to update their plugins earlier. :)

And with regard to jQuery4CMSimple: include_jQuery(), include_jQueryUI() and include_jQueryPlugin() could call the new function to add scripts, after filtering out duplicate requests. Maybe we'd need something like prependScript(), too, in this case.
Christoph M. Becker – Plugins for CMSimple_XH

Holger
Site Admin
Posts: 3470
Joined: Mon May 19, 2008 7:10 pm
Location: Hessen, Germany

Re: XH 1.7: sprint #6

Post by Holger » Tue Apr 04, 2017 9:34 pm

cmb wrote:Hm, haven't thought about that, but it would be an option, too. In this case manipulating several of the global variables would be easy, but as the template has already been included, it might not make much sense to do so. Accessing the so far generated HTML would also be easy, but to modify it one would have to fiddle with PHP's output buffering – not necessarily hard, but somewhat error prone.

Yet another option would be to add a hook just before the template is included, or maybe even before the output buffering is started.
Some templates include additional JavaScripts. With regard of my intention, the hook becomes useless for those scripts. Okay, we have to deal with output buffering but I don't see a problem there.
cmb wrote:Anyhow, with regard to minification of CSS and JS, an enqueue system (perhaps just two functions: one for linking of stylesheets, and one for inclusion of JS files, similar to ::addScript() and ::addStylesheet()) might simplify things (no need to parse <link> and <script> elements), and we could integrate the minification code into the core in the first place. Plugins not yet using these functions would get no minification, but that might encourage plugin authors to update their plugins earlier. :)

And with regard to jQuery4CMSimple: include_jQuery(), include_jQueryUI() and include_jQueryPlugin() could call the new function to add scripts, after filtering out duplicate requests. Maybe we'd need something like prependScript(), too, in this case.
That seems to be the best choice in the long run. But it's for the moment not my intention.
I'd like to have a simple working solution without rewriting all plugins and templates. I'm not sure if we really need such a hook because everything is possible with userprelude.php too. But to make things comfortable, they should come as an easy to install plugin.

OTOH adding the hook is contrary to a future enqueue system: why should one rewrite his plugin / template when there is already a working solution?
Hmm, maybe we should leave things as they are :? .

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: XH 1.7: sprint #6

Post by cmb » Tue Apr 04, 2017 10:35 pm

Holger wrote:Some templates include additional JavaScripts. With regard of my intention, the hook becomes useless for those scripts. Okay, we have to deal with output buffering but I don't see a problem there.
Ah, I've overlooked that, thanks! And indeed, the output buffering isn't really a big deal.
Holger wrote:I'm not shure if we really need such a hook because everything is possible with userprelude.php too.
It's probably best to use userprelude.php only as last resort. If more than one extension wants to use it, it might be hard to explain how to (similar to userfuncs.php).
Holger wrote:OTOH adding the hook is contrary to a future enqueue system: why should one rewrite his plugin / template when there is already a working solution?
Yes, that's a point, but after all the rewrite isn't hard, and we still could enforce it by deprecating and later removing support for the "old way", some time after a new API will be available.

IMO, either a hook at the end of cms.php or XH_finalCleanUp() is generally useful. Consider BadWords_XH, for instance. To be able to filter out all "bad words" from the output, the plugin has to request the very page that is requested by the visitor again behind the scenes. With an appropriate hook this won't be necessary. Yet another good example would be an HTML cleaner (Tidy or HTMLPurifier) which could use this hook. And the potential options are countless: parse the full HTML as DOM tree, manipulate as desired, and echo it. There are some plugins which work this way (actually, they're working with regexps, though) on the page content, but might be even more useful when being able to work on the full HTML; I'm thinking of tg_popup and imageoptimizer, for instance.

And, well, the end of cms.php is actually just before XH_finalCleanUp() will be called, so we may even have two hooks, maybe XH_beforeFinalCleanUp() and XH_afterFinalCleanUp(), even though I don't like the term "final cleanup". The PHP manual calls the respective paramter of ob_start() $output_callback, and maybe we should adopt this abstraction (after all, registered callbacks might do anything but cleaning up), and rename XH_finalCleanUp() to XH_outputCallback(), and add hooks to register callbacks, namely XH_beforeOutputCallback() and XH_afterOutputCallback()?

If we want to stick with a single hook, I still tend to prefer to add it at the end of XH_finalCleanUp(), because (a) the "final" HTML is available at this point, and (b) the signature and responsibility of the actual callback appear to be pretty clear[1]: the callback takes the current HTML, and returns an appropriately modfied HTML.

[1] After having read the PHP ob_start() man page I have to revise my suggestion:
The registered callback function would receive the $html by-reference, so would be able to modify it as needed.
Consitently with ob_start(), the callback should accept the $html by-value, and return the (modified) $html. And frankly, I'd be happy to eschew introducing a reference parameter.
Christoph M. Becker – Plugins for CMSimple_XH

Holger
Site Admin
Posts: 3470
Joined: Mon May 19, 2008 7:10 pm
Location: Hessen, Germany

Re: XH 1.7: sprint #6

Post by Holger » Wed Apr 05, 2017 8:58 am

cmb wrote:And the potential options are countless
Indeed. Good examples!
cmb wrote:And, well, the end of cms.php is actually just before XH_finalCleanUp() will be called, so we may even have two hooks, maybe XH_beforeFinalCleanUp() and XH_afterFinalCleanUp(), even though I don't like the term "final cleanup". The PHP manual calls the respective paramter of ob_start() $output_callback, and maybe we should adopt this abstraction (after all, registered callbacks might do anything but cleaning up), and rename XH_finalCleanUp() to XH_outputCallback(), and add hooks to register callbacks, namely XH_beforeOutputCallback() and XH_afterOutputCallback()?
+1

But again: in my special task I need the full page html after the Template has loaded. That would require a third hook or userprelude.php :?

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: XH 1.7: sprint #6

Post by cmb » Wed Apr 05, 2017 10:09 am

Holger wrote:But again: in my special task I need the full page html after the Template has loaded. That would require a third hook or userprelude.php :?
Ah, I guess now I've got it! Inside of XH_finalCleanUp() PHP may have lost it's CWD, because PHP has already started the shutdown sequence, so any file access inside of XH_finalCleanUp() may not work as usual. Guess that makes any callback called from inside XH_finalCleanUp() less useful.

Anyhow, we could call a callback registered with XH_beforeFinalCleanUp() before XH_finalCleanUp() gets actually called, i.e. at the very end of cms.php. In this case the CWD would be unchanged, and everything works as expected. However, code after the template inclusion may not actually be called, for instance, if the template fatals. That may not be a real problem, though.

Another option would be to introduce something like:

Code: Select all

define('XH_CWD', getcwd()); 
and to require all file access to use this constant when done within a callback called from XH_finalCleanUp(), e.g. instead of

Code: Select all

is_dir($pth['folder']['plugins'])
one would have to do

Code: Select all

is_dir(XH_CWD . $pth['folder']['plugins'])
With the addition of XH_CWD, a single callback (XH_afterFinalClean()) appears to be sufficient for your task (and others as well), unless I'm overlooking something again.
Christoph M. Becker – Plugins for CMSimple_XH

Post Reply