[PHP] core.bbcode_cache_init

Request hook events and what data needs to be sent for the new hook system.
Post Reply
marcovo
Registered User
Posts: 7
Joined: Sat Nov 15, 2014 9:57 am

[PHP] core.bbcode_cache_init

Post by marcovo »

Identifier: core.bbcode_cache_init (or sth like that?)
Location: bbcode.php, bbcode_cache_init(), likely just after if (isset($rowset[$bbcode_id]))
Parameters: $rowset[$bbcode_id] (or just $bbcode_id, see explanation)
Explanation:
I'm currently busy porting the MathJax phpBB integration mod. This mod/extension adds one or two bbcodes, which require an external javascript library to be loaded. One of the code changes for phpBB 3.0 was in /includes/bbcode.php, as follows:

Code: Select all

				<find><![CDATA[					if (isset($rowset[$bbcode_id]))
					{]]></find>
				<action type="replace-with"><![CDATA[					global $config;

					if (isset($rowset[$bbcode_id]))
					{
						if (!empty($config['mathjax_enable']) && !empty($rowset[$bbcode_id]['is_math'])) 
						{
							$template->assign_var('S_ENABLE_MATHJAX', true);
						}
]]></action>
This code makes sure the external libraries aren't loaded when the bbcode isn't used on the current page. This may not only be useful for this extension, but for other bbcode extensions that use (external) libraries too, I guess.

As for how the event should be included I'm not entirely sure. Assuming the event will be placed in place where the above modification is made (somewhere near line 340), it would be best to pass $rowset[$bbcode_id] with the event, because it provides all required information. Alternatively, one can also pass $bbcode_id only, but then the extension would have to make extra database queries to receive the right information.

Maybe the event can also be generalised from custom bbcodes to all bbcodes, triggering the event just before foreach ($bbcode_ids as $bbcode_id). That would imply however, that $bbcode_id will be passed, and extra database queries would possibly be needed, as argued above. Also, in this case extra care must be taken by extension developers using this event, as if (isset($rowset[$bbcode_id])) hasn't been yet checked for them.

For my port the first option would suffice perfectly, but the second might also be considered.

User avatar
JoshyPHP
Registered User
Posts: 381
Joined: Fri Jul 08, 2011 9:43 pm

Re: [PHP] core.bbcode_cache_init

Post by JoshyPHP »

Have you considered loading the script in JavaScript? Perhaps something like that:

Code: Select all

if (typeof window.MathJax === 'undefined')
{
	var el = document.createElement('script');
	el.type  = 'text/javascript';
	el.async = true;
	el.src   = '//cdnjs.cloudflare.com/ajax/libs/mathjax/2.4.0/MathJax.js';
	document.getElementsByTagName('head')[0].appendChild(el);
}

marcovo
Registered User
Posts: 7
Joined: Sat Nov 15, 2014 9:57 am

Re: [PHP] core.bbcode_cache_init

Post by marcovo »

Do you mean including that piece of code with each bbcode? This poses a few problems I guess. The library isn't very fast in converting the math-tags to actual math. By this I mean, for one second or so you'll see [math ]-tags, and then they are replaced with formulas. If you create another <script > tag within a javascript condition, the inclusion of this file is delayed with another amount of time, delaying the entire process again. Additionally, if one has many formulas on one page, that if-statement is also executed may times. In fact if-statements shouldn't take too long, but it does include 8 lines of code each time the bbcode is used... Moreover, it's quite a dirty solution, for what could become a beautiful solution if the event is added.

I must say it would be a nice working solution, but I don't think it's a worthy replacement of an event-based solution.

User avatar
JoshyPHP
Registered User
Posts: 381
Joined: Fri Jul 08, 2011 9:43 pm

Re: [PHP] core.bbcode_cache_init

Post by JoshyPHP »

Yes, you would use JavaScript in a normal script tag in your BBCode's template. I find it beautiful in its simplicity. It's self-contained and it requires neither events nor template variables or template bits.

I tested the following locally. It contains a guard against multiple execution.

Code: Select all

(function(d)
{
	if (typeof MathJax === typeof MathJaxLoading)
	{
		MathJaxLoading = 1;
		var s = d.createElement('script');
		s.type  = 'text/javascript';
		s.async = true;
		s.src   = '//cdn.mathjax.org/mathjax/latest/MathJax.js?config=AM_HTMLorMML-full';
		d.head.appendChild(s);
	}
})(document);
It gets minified to the following:

Code: Select all

(function(b){if(typeof MathJax===typeof MathJaxLoading){MathJaxLoading=1;var a=b.createElement("script");a.type="text/javascript";a.async=!0;a.src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=AM_HTMLorMML-full";b.head.appendChild(a)}})(document)
marcovo wrote:If you create another <script > tag within a javascript condition, the inclusion of this file is delayed with another amount of time, delaying the entire process again.
By how much do you think it would be delayed? If there's no script in head the code should be executed immediately and the script loads at about the same time as it would if it had been hardcoded in the page. Give or take a millisecond.

Talking about performance, I'd like to point out that events aren't free either and their overhead applies even when they're not being used.

marcovo
Registered User
Posts: 7
Joined: Sat Nov 15, 2014 9:57 am

Re: [PHP] core.bbcode_cache_init

Post by marcovo »

Thanks for your suggestions. I'll look into it, and indeed investigate whether there is a noticable delay when using such a JIT-inclusion (I guess you could call it that way :P ) or events.

User avatar
JoshyPHP
Registered User
Posts: 381
Joined: Fri Jul 08, 2011 9:43 pm

Re: [PHP] core.bbcode_cache_init

Post by JoshyPHP »

Cool. Be sure to share your findings here, that's an interesting subject. Thanks.

marcovo
Registered User
Posts: 7
Joined: Sat Nov 15, 2014 9:57 am

Re: [PHP] core.bbcode_cache_init

Post by marcovo »

As there is now a event included in phpBB3.1.3, core.bbcode_cache_init_end, I didn't really look into timing any more.
What I did notice:
- An event that has no subscribers takes 2e-5 seconds to execute (=0.00002 seconds)
- An event that has one subscriber with no further code (so, an empty function), takes about 5e-5 seconds to execute. The first run takes a little longer, about 1.1e-4s (presumably because of an initialization of something)

Post Reply