Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#13 2008-03-29 06:14:42

jm
Plugin Author
From: Missoula, MT
Registered: 2005-11-27
Posts: 1,746
Website

Re: Example code for a plugin that does this...

Reducing the hackinicity (it’s late):

  • I would use extract on the non-class function – your tag – and pass the attributes to __constructor.
  • Use $GLOBALS for small stuff:
function mah_replace_this_tag() {
	return $GLOBALS['mah_test_plugin_instance']->doStuff();
}

Also, be sure to prefix $instance too, since it is a global variable (updated the example – whoops!).

Last edited by jm (2008-03-29 06:27:42)

Offline

#14 2008-03-29 16:45:45

hakjoon
Member
From: Arlington, VA
Registered: 2004-07-29
Posts: 1,634
Website

Re: Example code for a plugin that does this...

its probably not a bad idea to destroy the global after youvare done with it. So if your individual tags are only meant to work inside the container tags you can unset the global after calling parse.

This also keeps users from using the tags where they might not work.

Oh and I would keep passing $atts to the constructor. To me that makes it much easier to add other attributes later because you only have to validate it in one place. Other wise everytime you add an attribute you need to update the constructor and the call to the constructor if you just pass $atts its just adding stuff to latts() of course YMMV

Last edited by hakjoon (2008-03-29 16:51:14)


Shoving is the answer – pusher robot

Offline

#15 2008-03-30 05:39:06

mhulse
Plugin Author
From: Eugene Oregon
Registered: 2005-01-21
Posts: 200

Re: Example code for a plugin that does this...

Thanks jm and hakjoon! Great tips! :)

I am not sure if I have the brain power to do more coding tonight, but for sure tomorrow!

I am sure I will have questions then.

For now, where does parse() live? I am wondering if I could write my own parse() function, and have it look at (for example) $this->mah_replace_this_tag() (in other words, have the parse() method look within a class for a method, instead of just a function… Hehe, make sense?)

Although, I think I need to do some more thinking about all of this… You know, always learning new things every day! ;)

A billion thanks!

Cheers,
Micky

Last edited by mhulse (2008-03-30 05:40:56)

Offline

#16 2008-03-30 06:46:08

jm
Plugin Author
From: Missoula, MT
Registered: 2005-11-27
Posts: 1,746
Website

Re: Example code for a plugin that does this...

mhulse wrote:

For now, where does parse() live?

Line 926 of textpattern/publish.php

I am wondering if I could write my own parse() function, and have it look at (for example) $this->mah_replace_this_tag() (in other words, have the parse() method look within a class for a method, instead of just a function… Hehe, make sense?)

So you’re trying to avoid writing mah_replace_this_tag as a function? I think the problem you might run into is TXP will tell you <txp:mah_replace_this_tag/> doesn’t exist, even if you write your own parse method.

Last edited by jm (2008-03-30 06:46:43)

Offline

#17 2008-03-30 06:57:02

mhulse
Plugin Author
From: Eugene Oregon
Registered: 2005-01-21
Posts: 200

Re: Example code for a plugin that does this...

jm wrote:

Line 926 of textpattern/publish.php

Thanks! Hehe, that was the one file I did not look in. :(

So you’re trying to avoid writing mah_replace_this_tag as a function? I think the problem you might run into is TXP will tell you <txp:mah_replace_this_tag/> doesn’t exist, even if you write your own parse method.

Well, I was thinking I might try to re-write parse() to work with class methods, instead of just functions (not in a class.)

In other words, I could call my own parse() method, from within my plugin class, and have it look for class methods (from within the class that it, parse(), is being called from.)

… I really need to open and study parse() though, I could be way off base with my thinking on this one. :D

Thanks for the reply jm! I really appreciate your help and professional advice!

Cheers,
Micky

Last edited by mhulse (2008-03-30 06:58:22)

Offline

#18 2008-03-30 15:45:59

hakjoon
Member
From: Arlington, VA
Registered: 2004-07-29
Posts: 1,634
Website

Re: Example code for a plugin that does this...

Not sure if it still does it this way but upm_image used to do its own tag replacing without relying on parse. It would run $thing through str_replace or something for its own tags and then run it through parse. I don’t think parse will try to process the contents of your container unless you explicitly tell it to.

This also saves you the need to create the global. The benefit of using the global and parse is that other plugins can be made to work with the infrastructure you are building without having to alter your code.


Shoving is the answer – pusher robot

Offline

#19 2008-03-31 00:27:40

Mary
Sock Enthusiast
Registered: 2004-06-27
Posts: 6,236

Re: Example code for a plugin that does this...

Yep, it used to, not anymore. It was just a simple str_replace() job on $thing.

Offline

#20 2008-03-31 05:40:23

mhulse
Plugin Author
From: Eugene Oregon
Registered: 2005-01-21
Posts: 200

Re: Example code for a plugin that does this...

Hey all, thanks again for the input! :)

I have not had much time to dink, but here is my latest attempt:

(Note: I have yet to apply some of the pro suggestions and coding tips offered in this thread… that is next on my to-do list.)

HTML:

<txp:mah_test_plugin path="/path/from/root/">
	Hello, <txp:mah_replace_this_tag />
</txp:mah_test_plugin>

PHP:

function mah_test_plugin($atts, $thing) {
	global $instance; // Instantiate global.
	$instance = new Mah_Test_Plugin($atts); // Create object.
	$out = mah_parse($thing); // Parse the plugin.
	return $out; // Finished.
}
class Mah_Test_Plugin {
	// Class variables:
	var $atts_path = "";
	// Constructor:
	function Mah_Test_Plugin($atts) {
		extract(lAtts(array(
			'path' => ''
		), $atts));
		$this->atts_path = $path;
	}
	// Class method:
	function doStuff() {
		return $this->atts_path;
	}
	function mah_replace_this_tag() {
		return $this->doStuff();
	}
}

(Next two modifed functions pulled from textpattern/publish.php)

function mah_parse($text) {
	$f = '/<txp:(\S+)\b(.*)(?:(?<!br )(\/))?'.chr(62).'(?(3)|(.+)<\/txp:\1>)/sU';
	return preg_replace_callback($f, 'mah_processTags', $text);
}
function mah_processTags($matches) {
	global $instance; // If set, mah_processTags() will look/use a class method. Otherwise, it will look/use a funciton.
	global $pretext, $production_status, $txptrace, $txptracelevel, $txp_current_tag;
	$tag = $matches[1];
	$trouble_makers = array('link');
	if (in_array($tag, $trouble_makers)) {
		$tag = 'tpt_'.$tag;
	}
	$atts = isset($matches[2]) ? splat($matches[2]) : '';
	$thing = isset($matches[4]) ? $matches[4] : null;
	$old_tag = @$txp_current_tag;
	$txp_current_tag = '<txp:' . $tag . ($atts ? $matches[2] : '') . ($thing ? '>' : '/>');
	trace_add($txp_current_tag);
	@++$txptracelevel;
	if ($production_status == 'debug') {
		maxMemUsage(trim($matches[0]));
	}
	$out = '';
	if(method_exists($instance, $tag)) {
		// Use class method:
		$out = $instance->$tag($atts, $thing, $matches[0]); 
	} elseif(function_exists($tag)) {
		// Use function:
		$out = $tag($atts, $thing, $matches[0]);
	// deprecated, remove in crockery
	} elseif(isset($pretext[$tag])) {
		$out = htmlspecialchars($pretext[$tag]);
		trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
	} else {
		trigger_error(gTxt('unknown_tag'), E_USER_WARNING);
	}
	@--$txptracelevel;
	if(isset($matches[4])) {
		trace_add('</txp:'.$tag.'>');
	}
	$txp_current_tag = $old_tag;
	return $out;
}

Output:

Hello, /path/from/root/

Heehee, not sure if that is going totally overboard… But I kinda like it better than my previous approach.

I may just look inot using str_replace though.

Fun stuff!

Cheers,
Micky

Last edited by mhulse (2008-03-31 06:19:01)

Offline

Board footer

Powered by FluxBB