contao/test — Issue #1348: Allow Subfolder Support in the Templates Folder
Author: importer
Created: 2011-11-29 07:46:33+00:00
State: open
Labels: Duplicate, Feature, framework

Hi Leo,

I wanted to take another crack at this issue: http://dev.typolight.org/issues/show/46#change-144

Being able to organize and group custom templates into subfolders would be very valuable, both when maintaining a site with many custom templates, and also as a convenience when migrating/reusing custom templates across multiple sites.

My solution below allows you to place your template files any folder structure you choose. In the case of naming conflicts (multiple files of the same name in different folders), the file in the parent directory takes precedence. After that, folders are parsed alphabetically (staying consistent with how you parse modules) -- so 'templates/mytemplate.tpl takes precedence over '/templates/b/mytemplate.tpl' which takes precedence over '/templates/a/mytemplate.tpl'.

My solution also does not break the template editor -- files can be browsed to and edited normally.

This solution was tested on 2.8RC2.

**The first thing I did was add an additional function, _getSubFolders()_, to _functions.php_.**
This function accepts a string containing the path to the base folder you wish to parse, and optionally an array of filters to exclude certain folders from being searched ("." and ".." are excluded automatically). It returns a flat, one-dimensional array containing the paths to all subfolders off the base.

```
function getSubFolders($strBaseFolder, $arrFilters = array())
{
$strBaseFolder = rtrim($strBaseFolder, '/');
$arrFilters = array_merge(Array(".", ".."), $arrFilters);
$arrFolders = array();

foreach (array_diff(scandir($strBaseFolder), $arrFilters) as $strFileName)
{
$strTempPath = $strBaseFolder . "/" . $strFileName;

if (is_dir($strTempPath))
{

$arrFolders[] = $strTempPath . '/';
$arrFolders = array_merge(getSubFolders($strTempPath), $arrFolders);
}
}

return $arrFolders;
}
```

**Next I altered the _getTemplates()_ function:**

```
protected function getTemplate($strTemplate)
{
$strTemplate = basename($strTemplate);
$arrLocations = array_merge(getSubFolders(TL_ROOT . '/templates/'), array(TL_ROOT . '/templates/'));

foreach($arrLocations as $strTempPath)
{
$strTempFile = $strTempPath . $strTemplate . '.tpl';

if (file_exists($strTempFile))
{
$strFile = $strTempFile;
}
}

if (

![](file_exists($strFile))
{
foreach ($this->Config->getActiveModules() as $strModule)
{
$strPath = sprintf('%s/system/modules/%s/templates/%s.tpl', TL_ROOT, $strModule, $strTemplate);

if (file_exists($strPath))
{
$strFile = $strPath;
break;
}
}
}

if ()file_exists($strFile))
{
throw new Exception(sprintf('Could not find template file "%s"', $strTemplate));
}

return $strFile;
}
```

**And finally, I altered the _getTemplateGroup()_ function:**

```
protected function getTemplateGroup($strPrefix)
{
$arrTemplates = array();
$arrFolders = array_merge(getSubFolders(TL_ROOT . '/templates/'), array(TL_ROOT . '/templates/'));

foreach ($this->Config->getActiveModules() as $strModule)
{
$strFolder = sprintf('%s/system/modules/%s/templates', TL_ROOT, $strModule);

if (is_dir($strFolder))
{
$arrFolders[] = $strFolder;
}
}

foreach ($arrFolders as $strFolder)
{
$arrFiles = preg_grep('/^' . preg_quote($strPrefix, '/') . '.*\.tpl$/i', scan($strFolder));

foreach ($arrFiles as $strTemplate)
{
$arrTemplates[] = basename($strTemplate, '.tpl');
}
}

natcasesort($arrTemplates);
return array_values(array_unique($arrTemplates));
}
```

Related issues: #46

--- _Originally created by Medianomaly on January 2nd, 2010, at 09:53pm (ID 1348)_