Hacking Textpattern Plugins

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
Ace of Dubs
Forum Newbie
Posts: 2
Joined: Sun Aug 06, 2006 9:55 am

Hacking Textpattern Plugins

Post by Ace of Dubs »

So I been getting my PHP feet wet lately with Textpattern's CMS and through basic logic and piecing together strips of code, I have so far been able to hack the admin and a few plugins to my advantage. I was actually surprised how simple PHP can be. Recently though I hit a brick wall and could use some advice.

Basically there is this great plugin that allows you to paginate articles simply by placing [page] in your body field. The plugin generates the pages and navigation on the fly. The problem is that it only provides the option of listing pages as numbers and doesnt allow you to title your pages either.

Enter the Arkham Hack, a modification which allows you to place [page Title Goes Here] and also shows your title as a teaser link for the next page. As far as I can tell, here is the bit of code that handles this... note the references to "teaser"

Code: Select all

function etz_pg_body($atts) {
	global $thisarticle;
	$pageSep = etz_pg_break();


	if (is_array($atts)) extract($atts);
	$pgerr     = isset($pgerr) ? $pgerr : 'Invalid page number!';
	$notrim    = isset($notrim) ? $notrim : false;
	$pg        = etz_pg_thispage();
	$pages     = preg_split($pageSep, $thisarticle['body']);
	$max       = count($pages) + 1;
        $linkstub = etz_pg_linkstub();

        preg_match_all($pageSep, $thisarticle['body'],  $matches);
        
        $teaser = $matches[1][$pg-1];


	if ($pg == "all") {
		return join("\n", $pages);
	}
	else {
		if (isset($pages[$pg-1])) {

			$pagecontent = $pages[$pg-1];
			if (($pg > 1) && (!($notrim))) $pagecontent = substr($pagecontent, 4);
			if (($pg < $max) && (!($notrim))) $pagecontent = substr($pagecontent, 0, -3);
			if (!empty($teaser)) return $pagecontent.'<p id="teaserTxt"><a href="'.$linkstub.($pg + 1).'">'.$teaser.'</a></p>';
                        else return $pagecontent;
		}
		else {
			return '<p>'.$pgerr.'</p>';
		}
	}
}

My aim is to take it a step further and have all the titles show up as an unordered navigation list..
Here are a few clues from Arkham's post on how to accomplish this:
(to modify this) as an overall navigation option (a list of all page titles). The nav function can be easily modified to handle that by making use of the same code from etz_pg_body:

preg_match_all($pageSep, $thisarticle[‘body’], $matches);

$matches [ 1 ][0] would now have the 1st page title. $matches [ 1 ][1] the second and so on…

In this case you’d need to add another option to the tag etz_pg to control whether this type of page title navigation should be used
So I took his advice and decided to poke around with the "nonumbers" function which creates the current navigation:

Code: Select all

if (!($nonumbers)) {
			for ($i = 1; $i <= $max; $i++) {
				$out[] = '<li class="pgNum';

                               if ($i == $max) {
                                      $out[] = ' pgLast';
                                 }
				if ($pg != $i) {
					if ($i == 1) {
						$out[] = '"><a href="'.$base_url.'">';
					}
					else {$out[] = '"><a href="'.$linkstub.($i).'">';
					}
				}
				else {
						$out[] = ' pgCurrent">';
				}
				$out[] = $i;
				if ($pg != $i) $out[] = '</a>';
				$out[] = ' ';
				$out[] = '</li>';
			}
		}
I have tried hacking it up a hundred different ways, but my pathetic PHP skills havent saved the day yet. I have no idea how to create the option that Arkham refers to, and niether he nor the plugin author have answered my emails.

I feel like I am close to the solution but missing a small nudge in the right direction. How would you tackle this problem?
Ace of Dubs
Forum Newbie
Posts: 2
Joined: Sun Aug 06, 2006 9:55 am

Post by Ace of Dubs »

I have made some progress on this.

Here is the relevant code the author uses to output his fancy title listing:

Here is the setup:

Code: Select all

preg_match_all($pageSep, $thisarticle['body'],  $matches);

$teaser = $matches[1][$pg-1];
This is what displays the title of the next page:

Code: Select all

if (!empty($teaser)) return $pagecontent.'<p id="teaserTxt"><a href="'.$linkstub.($pg + 1).'">'.$teaser.'</a></p>';
 else return $pagecontent;
So I decided to define a new attribute with the others, and make it true instead of false, so that it is off by default and an entry of "1" will turn it on:

Code: Select all

$titles = isset($titles) ? $titles : true;
Then I lift the code from the numerical list and call it titles as well

Code: Select all

if (!($titles)) {
    for ($i = 1; $i <= $max; $i++) {
		$out[] = '<li class="pgNum';

                       if ($i == $max) {
                              $out[] = ' pgLast';
                         }
		if ($pg != $i) {
			if ($i == 1) {
				$out[] = '"><a href="'.$base_url.'">';
			}
			else {$out[] = '"><a href="'.$linkstub.($i).'">';
			}
		}
		else {
				$out[] = ' pgCurrent">';
		}
		
		$out[] = $i;
		if ($pg != $i) $out[] = '</a>';
		$out[] = ' ';
		$out[] = '</li>';
	}
}
I test it and see that its still outputting numbers, of course I haven't set up my teaser yet.. so I track down the number output from above as follows:

Code: Select all

$out[] = $i;
Awesome.. I have pinpointed my target, but I still have not figured out how to create the relationship between my attribute and the rest of the article titles.

I tried modding the above snippet:

Code: Select all

$out[] = $teaser;
But that fails and I think my problem lies where I first started:

Code: Select all

preg_match_all($pageSep, $thisarticle['body'],  $matches);

$teaser = $matches[1][$pg-1];
I realize that I need to create a new variable instead of teaser. I just don't understand how to link this properly to $matches in order to spit out the page titles instead of their numbers.

Any ideas?
Post Reply