Help with Separating Function and Markup

Hey Guys

PHP newbie here.

I have the following PHP code that generated and prints HTML.

<?php

function checkPath()
{
	$directoryUrl = ($_GET['path'] == "" ? "audio_files/voices/female/" : $_GET['path']);
	
	return $directoryUrl;
}

function genList()
{
	$excludes = array(".","..",".DS_Store",".svn");

	$directoryUrl = checkPath();

	$itemList = scandir($directoryUrl) or die("Unable to Access $directoryUrl");

	foreach ($itemList as $item)
	{
		if (!in_array("$item", $excludes))
		{
		print "
	
		<li class='sample_li'>
			<h2>$item</h2>
			<ul>
				<li>
					<span class='label'>Select a sample: </span>
				</li>";

		$subDirectory = $directoryUrl.$item;
		
		$subItemList = scandir($subDirectory) or die("Unable to Access $subDirectory");
		
		foreach ($subItemList as $subItem)
		{
			if (!in_array("$subItem", $excludes))
			{
				$file = str_replace(".mp3", "", $subItem);
				print "
		
				<li>
					<a href='#' id='track-0'>$file</a>
				</li>";
			}
		}

		print "

			</ul>
			<p>
				<span class='label'>Now Playing:</span>
				<span class='now_playing' id='trackname'>Relaxed</span>
				<span class='pcent' id='pcent'>37%</span>
			</p>
			<ul class='controls'>
				<li>
					<a href='#' id='play'>Play</a>
				</li>
				<li>
					<a href='#' id='pause'>Pause</a>
				</li>
				<li>
					<span> ~ </span>
					<a href='#' id='stop'>Stop</a>
				</li>
				<li>
					<span> ~ </span>
					<a href='#' id='download'>Download</a>
				</li>
			</ul>
		</li>";
		}
	}
}

?>

However I feel that it would be cleaner if the function and the markup were separate however I am not sure how to do this given the nature of the function structure.

Any help would be really appreciated.

Thanks :slight_smile:

Solution depends on the template system you choose.

If you’d go for PHP as a template language, just make your function return an array and use it later in template.

I’ve noticed in the WordPress widgets file the mark-up is assigned to variables which are then used later. eg.

$before_item = "<li class='sample_li'><h2>";
$after_item = "</h2><ul><li><span class='label'>Select a sample: </span></li>";
print $before_item . $item . $after_item;

I don’t know as it makes things much “cleaner”, but it keeps things more separate.

oh. this last one is terriblest of spaghetti code.

Really, one should first determine purpose of such separation first.

You can try something like this:


<?php
#
# This is your business logic
#

# Get all files in a map
function getDirectoryTree( $outerDir ){
    $dirs = array_diff( scandir( $outerDir ), Array( ".", ".." ) );
    $dir_array = Array();
    foreach( $dirs as $d ){
        if( is_dir($outerDir."/".$d) ) $dir_array[ $d ] = getDirectoryTree( $outerDir."/".$d );
        else $dir_array[ $d ] = $d;
    }
    return $dir_array;
}


#
#  This is your display logic helpers
#

# print the files
function print_data($files) {
  echo '<ul>';
  foreach ($files as $key => $value) {
    # If this is a folder, show what's in it
    if (is_array($value)) {
      print_data($value);
    } else {
      echo '<li><a href="#">'.$value.'</a></li>';
    }
  }
  echo '</ul>';
}

#
#  This is your display logic
#
?>

<?php print_data(getDirectoryTree('/home/user/app/data/songs/')); ?>
<p>
  <span class='label'>Now Playing:</span>
  <span class='now_playing' id='trackname'>Relaxed</span>
  <span class='pcent' id='pcent'>37&#37;</span>
</p>
<ul class='controls'>
  <li>
    <a href='#' id='play'>Play</a>
  </li>
  <li>
    <a href='#' id='pause'>Pause</a>
  </li>
  <li>
    <span> ~ </span>
    <a href='#' id='stop'>Stop</a>
  </li>
  <li>
    <span> ~ </span>
    <a href='#' id='download'>Download</a>
  </li>
</ul>

You can probably look at array_map / array_walk so you don’t have the recursive function any more.