Reducing Template Code

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Reducing Template Code

Post by Jonah Bron »

Code: Select all

<aside id="docTree">
<?php

$tree = array();

global $documents, $template, $parents, $slug;

$documents = $doc_tree->fetchAll()->toArray();
$template = <<<EOS
%1\$s	<li%5\$s>
%1\$s		<span><button></button><a href="{$BASE}support/docs/browse/%2\$s">%3\$s</a></span>
%4\$s
%1\$s	</li>

EOS;
$slug = $doc_slug;
$parents = array();
$currentParent = $doc_slug;
while ($currentParent != 'root' && $currentParent != 'error') {
	foreach ($documents as $document) {
		if ($document->slug == $currentParent) {
			$parents[] = $document->slug;
			$currentParent = $document->parent;
		}
	}
}

function scanForChildren($parent, $stackDepth=0) {
	global $documents, $template, $parents, $slug;
	// indent two tabs at a time
	$indent = str_repeat('		', $stackDepth);
	$html = "$indent<ul>\n";
	foreach ($documents as $doc) {
		if ($doc->parent == $parent) {
			$html .= sprintf(
				$template,
				$indent,
				$doc->slug,
				$doc->title,
				scanForChildren($doc->slug, $stackDepth + 1),
				in_array($doc->slug, $parents) ? ($doc->slug == $slug ? ' class="current"' : '') : ' class="closed"'
			);
		}
	}
	$html .= "$indent</ul>\n";
	return $html;
}

echo scanForChildren('root', 1);

?>
</aside>
This mess of code is in a template file in the context of a Skeleton Framework application. It's purpose probably isn't immediately apparent, so I'll explain: this code takes a linear array of document names and in one-to-many relationships, and displays it in tree form. Each document's children can be hidden and shown (with Javascript) like any normal tree (think Eclipse file explorer).

The code is in "working" state. This is clearly view code (as in model view controller), but it seems like there shouldn't be so much (procedural) code in the template file. Plus it ranks of an absence of SRP. To top it off, the main recursive function holds multiple levels of abstraction in itself (conversion, HTML output, etc.).

What I do about this?

P.S. the $stackDepth and $indent variables are strictly to make the markup look pretty :)

Edit: here's an example output:

Code: Select all

<aside id="docTree">
	<ul>
		<li class="closed">
			<span><button></button><a href="http://localhost/batchzip/support/docs/browse/home">Home</a></span>
			<ul>
			</ul>

		</li>
		<li class="closed">
			<span><button></button><a href="http://localhost/batchzip/support/docs/browse/sub">Sub Page</a></span>
			<ul>
			</ul>

		</li>
		<li class="closed">
			<span><button></button><a href="http://localhost/batchzip/support/docs/browse/subsub">Sub Sub page</a></span>
			<ul>
				<li class="closed">
					<span><button></button><a href="http://localhost/batchzip/support/docs/browse/foo">Foo</a></span>
					<ul>
						<li class="closed">
							<span><button></button><a href="http://localhost/batchzip/support/docs/browse/bar">Bar</a></span>
							<ul>
							</ul>

						</li>
					</ul>

				</li>
			</ul>

		</li>
		<li class="closed">
			<span><button></button><a href="http://localhost/batchzip/support/docs/browse/top">Top Level</a></span>
			<ul>
			</ul>

		</li>
	</ul>

</aside>
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: Reducing Template Code

Post by Jonah Bron »

John Cartwright wrote:two words:
view helper
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: Reducing Template Code

Post by Jonah Bron »

Hm, I've run into a problem. How can I create a recursive helper, while keeping the HTML in the template file, and the logic in the helper? Maybe the helper should execute a callback created by the template to output each nested item?
Post Reply