Forumlar / Cotonti / Core Labs / set metas from standalone plugin

12>>>

dervan
#1 2009-02-24 20:18
known problem:
impossible to set metas from standalone plugin

the cause of problem:
header is included and parsed before launching of standalone plugin

possible solution:
header may be included (with pointers technique) after launching of standalone plugin

this solution works without problems in Seditio 121
link (in russian)


code from current system/core/plug/plug.inc.php in trac:
	/* ============= */

	require_once $cfg['system_dir'] . '/header.php';

	$t = new XTemplate($path_skin);

	$extp = array();

	if (is_array($sed_plugins))
	{
		foreach($sed_plugins as $i => $k)
		{
			if ($k['pl_hook']=='standalone' && $k['pl_code']==$e)
			{ $extp[$i] = $k; }
		}
	}

	if (count($extp)==0)
	{
		header("Location: " . SED_ABSOLUTE_URL . sed_url('message', "msg=907", '', true));
		exit;
	}

	if (is_array($extp))
	{ foreach($extp as $k => $pl) { include_once($cfg['plugins_dir'].'/'.$pl['pl_code'].'/'.$pl['pl_file'].'.php'); } }

	if ($autoassigntags)
	{
		$plugin_title = (empty($plugin_title)) ? $L['plu_title'] : $plugin_title;

		if($cfg['homebreadcrumb'])
		{
			$bhome = '<a href="'.$cfg['mainurl'].'">'.sed_cc($cfg['maintitle']).'</a> '.$cfg['separator'].' ';
		}
		else
		{
			$bhome = '';
		}

		$t-> assign(array(
			"PLUGIN_TITLE" => $bhome . '<a href="'.sed_url('plug', "e=$e").'">'.$plugin_title."</a>",
			"PLUGIN_SUBTITLE" => $plugin_subtitle,
			"PLUGIN_BODY" => $plugin_body
		));
	}

	$t->parse("MAIN");
	$t->out("MAIN");

	require_once $cfg['system_dir'] . '/footer.php';


modified code with this solution:
	/* ============= */

	$t_plug = new XTemplate($path_skin);
	$t =& $t_plug;

	$extp = array();

	if (is_array($sed_plugins))
	{
		foreach($sed_plugins as $i => $k)
		{
			if ($k['pl_hook']=='standalone' && $k['pl_code']==$e)
			{ $extp[$i] = $k; }
		}
	}

	if (count($extp)==0)
	{
		header("Location: " . SED_ABSOLUTE_URL . sed_url('message', "msg=907", '', true));
		exit;
	}

	if (is_array($extp))
	{ foreach($extp as $k => $pl) { include_once($cfg['plugins_dir'].'/'.$pl['pl_code'].'/'.$pl['pl_file'].'.php'); } }

	unset($t);
	require_once $cfg['system_dir'] . '/header.php';
	unset($t);
	$t =& $t_plug;

	if ($autoassigntags)
	{
		$plugin_title = (empty($plugin_title)) ? $L['plu_title'] : $plugin_title;

		if($cfg['homebreadcrumb'])
		{
			$bhome = '<a href="'.$cfg['mainurl'].'">'.sed_cc($cfg['maintitle']).'</a> '.$cfg['separator'].' ';
		}
		else
		{
			$bhome = '';
		}

		$t-> assign(array(
			"PLUGIN_TITLE" => $bhome . '<a href="'.sed_url('plug', "e=$e").'">'.$plugin_title."</a>",
			"PLUGIN_SUBTITLE" => $plugin_subtitle,
			"PLUGIN_BODY" => $plugin_body
		));
	}

	$t->parse("MAIN");
	$t->out("MAIN");
	unset($t, $t_plug);

	require_once $cfg['system_dir'] . '/footer.php';
Kilandor
#2 2009-02-24 20:26
There is no need for this, actually you can modify things in the <head> section. Because we no longer use sed_htmlmetas() except for in pfs and thats only till its re-written.

$out['head_head'] may be used to input any needed data into <head></head> it outputs to {HEADER_HEAD} and is a default tag.

Actually all of the below can easily be modified. by hooking into header.main

$t->assign(array (
	"HEADER_TITLE" => $plug_title.$out['fulltitle'],
	"HEADER_DOCTYPE" => $cfg['doctype'],
	"HEADER_CSS" => $cfg['css'],
	"HEADER_COMPOPUP" => $out['compopup'],
	"HEADER_LOGSTATUS" => $out['logstatus'],
	"HEADER_WHOSONLINE" => $out['whosonline'],
	"HEADER_TOPLINE" => $cfg['topline'],
	"HEADER_BANNER" => $cfg['banner'],
	"HEADER_GMTTIME" => $usr['gmttime'],
	"HEADER_USERLIST" => $out['userlist'],
	"HEADER_NOTICES" => $out['notices'],
	"HEADER_BASEHREF" => $out['basehref'],
	"HEADER_META_CONTENTTYPE" => $out['meta_contenttype'],
	"HEADER_META_CHARSET" => $out['meta_charset'],
	"HEADER_META_DESCRIPTION" => $out['meta_desc'],
	"HEADER_META_KEYWORDS" => $out['meta_keywords'],
	"HEADER_META_LASTMODIFIED" => $out['meta_lastmod'],
	"HEADER_HEAD" => $out['head_head'],
));
Trustmaster
#3 2009-02-24 20:32
Disagreed with Kilandor. Mostly standalone plugs would like to put the results of some processing into keywords/title. If you do that with a special header plugin part, that means that you have to do the processing twice, which is a waste. So if dervan's suggestion does not have any negative consequences, I would prefer it.
May the Source be with you!
Orkan
#4 2009-02-25 03:16
I dunno why, but something tells me it isn't a good idea..

Some more specialized plugins may not work after this change.
And this will require at least 2 hooks, so why dont use hook:output for that?

$output = preg_replace(
'/<meta(.+)name="keywords"([^>]+)>/i', 
'<meta name="keywords" content="'.$my_plugin['meta_keywords'].'" />', 
$output, 1);
Perl - the only language that looks the same before and after RSA encryption.
Trustmaster
#5 2009-02-25 03:20
What we need to find out is what exactly those specialized plugins are.
May the Source be with you!
Orkan
#6 2009-02-25 03:42
anyway, it doesn't look too professional, isnt?

$t_plug = new XTemplate($path_skin);
$t =& $t_plug;

:-P
Perl - the only language that looks the same before and after RSA encryption.
dervan
#7 2009-02-25 04:29
Orkan, what is wrong in the use of pointers?
Trustmaster
#8 2009-02-25 04:44
It is deprecated in PHP5, because in PHP5 objects are passed by reference by default.
May the Source be with you!
dervan
#9 2009-02-25 05:19
Trustmaster, thanks
Kilandor
#10 2009-02-25 11:09
Actually using output hook in that method would be alot worse and more difficult orkan. Since all the keywords and such can be hooked into by header.main anyways.

The only way that moving where header is included would be if a plugin used any data generated by header, which is possible. Then it would completely break it, I truthfully don't know any off hand like this, but it may break future things like a more updated Whoisonline tracking method.

I can see the reason for moving it, but it doesn't solve all the problems. Also do remember this, we will be getting more advanced hooking methods, so that a hook is only loaded on certain pages/area's. By moving the header all it does is save that hook, and in some cases yes maybe extra processing.

The handling of $t won't be hard, i've already thought of how it can be done, because yes you have to store the $t from the plugin, and hold it till header parsed, then let main use the $t from the plugin.
Orkan
#11 2009-02-25 15:58
# dervan : Orkan, what is wrong in the use of pointers?

Well, all Im saying - it is not a procedural approach.
It should be avoided, like GOTO command in C++, it only makes the code more difficult to read.

From the other hand, what if I wanna use footer hook to set metas? see, its not perfect anyway...

I really like the output buffering feature implemented in PHP - it seems to be perfect solution here IMO.
You can have nesting buffers for all three parts: header, body and footer.. and hook them separately.

<?PHP
$counter = 0;

function callback_header($header)
{	
	global $counter;
	return (++$counter).' - callback_header(), content: '.$header.'<br>';
}
function callback_body($body)
{	
	global $counter;
	return (++$counter).' - callback_body(), content: '.$body.'<br>';
}
function callback_footer($footer)
{	
	global $counter;
	return (++$counter).' - callback_footer(), content: '.$footer.'<br>';
}


ob_start('callback_header');
echo 'echo_1_header<br>';

ob_start('callback_body');
echo 'echo_2_body<br>';

ob_start('callback_footer');
echo 'echo_3_footer<br>';

while(@ob_end_flush());


?>


and this will output:
3 - callback_header(), content: echo_1_header
2 - callback_body(), content: echo_2_body
1 - callback_footer(), content: echo_3_footer

see? the callback_header() is processed by ob_end_flush() last, but it is sent to the browser as first :-)


Also, to get rid of additional hook include()'s - which is a waste, one can define (in the core) three global arrays for preg_replace() to use in these callbacks accordingly.
Perl - the only language that looks the same before and after RSA encryption.

Bu konu Orkan tarafından düzenlendi(2009-02-25 16:53, 15 yıllar önce)
dervan
#12 2009-02-25 18:35
# Orkan : It should be avoided, like GOTO command in C++, it only makes the code more difficult to read.
no no no, not like goto :)
it's any little trick with $t object that used by header.php and plug.inc.php both


# Orkan : I really like the output buffering feature implemented in PHP - it seems to be perfect solution here IMO.
ol korekt :)
i'm awaiting for your solution of problem on this carcass
Orkan
#13 2009-02-25 20:18
# dervan :
no no no, not like goto :)
it's any little trick with $t object that used by header.php and plug.inc.php both

sorry, I didnt make myself clear enough. I mentioned GOTO as an example only. I understood your solution. however, you must admit that it only makes the code more difficult to read, right?

# dervan : i'm awaiting for your solution of problem on this carcass

this method is rather simple..
Basically each "main module", for example system/core/plug/plug.inc.php, should start with ob_start('name_of_callback_function') including header.php and footer.php as well.

just a note:

common.php
if ($cfg['gzip'])
	{ @ob_start('ob_gzhandler'); }
else
	{ ob_start(); }

ob_start('sed_outputfilters');

I would replace ob_start('sed_outputfilters') with just ob_start() to catch some warning messages, etc.. they will be discarded anyway at the end of common.php by simple @ob_end_clean(); - or even completely remove this buffer?

I can implement it, just want to hear from Kilandor, Trustmaster what they think?
Perl - the only language that looks the same before and after RSA encryption.

Bu konu Orkan tarafından düzenlendi(2009-02-25 20:32, 15 yıllar önce)
Trustmaster
#14 2009-02-25 21:25
What I don't like about parsing the output buffer is that it is fulltext parsing. Well, Seditio's advanced rewrite acted this way, and it added about 10% to render time. I know this one won't go so complex. But it doesn't look like strong design.
May the Source be with you!
Orkan
#15 2009-02-25 22:23
what do you mean by "it is fulltext parsing" ?

each callback will process only a part of "fulltext", ie. callback_header($header) will only process parsed header.tpl output
Perl - the only language that looks the same before and after RSA encryption.

12>>>