Rework template wrapper, bring back template_part()

This commit is contained in:
QWp6t
2016-07-15 05:31:02 -07:00
parent 0a71544b83
commit eb3a7add85
8 changed files with 130 additions and 109 deletions

View File

@@ -49,5 +49,5 @@ add_filter('template_include', function ($main) {
if (!is_string($main) && !(is_object($main) && method_exists($main, '__toString'))) { if (!is_string($main) && !(is_object($main) && method_exists($main, '__toString'))) {
return $main; return $main;
} }
return template_wrap(new Wrapper($main)); return ((new Template(new Wrapper($main)))->layout());
}, 109); }, 109);

View File

@@ -2,29 +2,17 @@
use Roots\Sage\Asset; use Roots\Sage\Asset;
use Roots\Sage\Assets\JsonManifest; use Roots\Sage\Assets\JsonManifest;
use Roots\Sage\Template\WrapperCollection; use Roots\Sage\Template;
use Roots\Sage\Template\WrapperInterface;
/** function template($layout = 'base')
* @param WrapperInterface $wrapper
* @param string $slug
* @return string
* @throws \Exception
* @SuppressWarnings(PHPMD.StaticAccess) This is a helper function, so we can suppress this warning
*/
function template_wrap(WrapperInterface $wrapper, $slug = 'base')
{ {
WrapperCollection::add($wrapper, $slug); return Template::$instances[$layout];
return $wrapper->getWrapper();
} }
/** function template_part($template, array $context = [], $layout = 'base')
* @param string $slug
* @return string
*/
function template_unwrap($slug = 'base')
{ {
return WrapperCollection::get($slug)->getTemplate(); extract($context);
include template($layout)->partial($template);
} }
/** /**

44
src/lib/Sage/Template.php Normal file
View File

@@ -0,0 +1,44 @@
<?php namespace Roots\Sage;
use Roots\Sage\Template\Partial;
use Roots\Sage\Template\WrapperInterface;
class Template
{
/** @var Template[] */
public static $instances = [];
/** @var WrapperInterface */
protected $wrapper;
public function __construct(WrapperInterface $wrapper)
{
$this->wrapper = $wrapper;
self::$instances[$wrapper->slug()] = $this;
}
/**
* @return string Layout (FQPN of, e.g., `base-page.php`, `base.php`)
*/
public function layout()
{
return $this->wrapper->wrap();
}
/**
* @return string Main template (FQPN of, e.g., `page.php`, `single.php`, `singular.php`)
*/
public function main()
{
return $this->wrapper->unwrap();
}
/**
* @param string $template Delimited template path
* @return string Partial template (FQPN of, e.g., `content.php`, `page-header.php`
*/
public function partial($template)
{
return (new Partial($template, $this->main()))->path();
}
}

View File

@@ -0,0 +1,70 @@
<?php namespace Roots\Sage\Template;
class Partial
{
protected static $cache = [];
public $main;
public $template;
public $delimiter = '-';
public function __construct($template, $main = '')
{
$this->template = $template;
$this->main = $main;
}
public function __toString()
{
return (string) $this->path();
}
/**
* Converts template into array of parts to be passed to locate_template()
*
* Here's an example of what happens:
* (new Template('partials/content-single-audio'))->parts();
* // => ['partials/content-single-audio.php', 'partials/content-single.php', 'partials/content.php']
* @return array Array of parts to pass to locate_template()
*/
public function parts()
{
if ($parts = $this->cache('parts')) {
return $parts;
}
$parts = explode($this->delimiter, str_replace('.php', '', $this->template));
$templates[] = array_shift($parts);
foreach ($parts as $i => $part) {
$templates[] = $templates[$i] . $this->delimiter . $part;
}
if ($this->main) {
$templates = array_merge($templates, array_map(function ($template) {
return $template . $this->delimiter . basename($this->main, '.php');
}, $templates));
}
$templates = array_map(function ($template) {
return $template . '.php';
}, $templates);
return $this->cache('parts', array_reverse($templates));
}
/**
* Passes $this->parts() to locate_template() to retrieve template location
* @return string Location of template
*/
public function path()
{
if (!$path = $this->cache('path')) {
$path = $this->cache('path', locate_template($this->parts()));
}
return apply_filters('sage/partial_' . basename($path, '.php'), $path, $this->parts()) ?: $path;
}
protected function cache($key, $value = null)
{
if ($value !== null) {
self::$cache[$this->template][$key] = $value;
}
return isset(self::$cache[$this->template][$key]) ? self::$cache[$this->template][$key] : null;
}
}

View File

@@ -37,24 +37,24 @@ class Wrapper implements WrapperInterface
*/ */
public function __toString() public function __toString()
{ {
return $this->getTemplate(); return $this->unwrap();
} }
/** {@inheritdoc} */ /** {@inheritdoc} */
public function getWrapper() public function wrap()
{ {
$wrappers = apply_filters('sage/wrap_' . $this->slug, $this->wrapper) ?: $this->wrapper; $wrappers = apply_filters('sage/wrap_' . $this->slug, $this->wrapper) ?: $this->wrapper;
return locate_template($wrappers); return locate_template($wrappers);
} }
/** {@inheritdoc} */ /** {@inheritdoc} */
public function getSlug() public function slug()
{ {
return $this->slug; return $this->slug;
} }
/** {@inheritdoc} */ /** {@inheritdoc} */
public function getTemplate() public function unwrap()
{ {
$template = apply_filters('sage/unwrap_' . $this->slug, $this->template) ?: $this->template; $template = apply_filters('sage/unwrap_' . $this->slug, $this->template) ?: $this->template;
return locate_template($template) ?: $template; return locate_template($template) ?: $template;

View File

@@ -1,81 +0,0 @@
<?php namespace Roots\Sage\Template;
/**
* Class Wrapper
* @package Roots\Sage
* @author QWp6t
*/
class WrapperCollection
{
/** @var $this */
protected static $instance;
/** @var WrapperInterface[] $wrappers */
protected $wrappers = [];
/** Singleton */
// @codingStandardsIgnoreStart
private function __construct() {}
private function __clone() {}
// @codingStandardsIgnoreEnd
/**
* @return static
*/
public static function instance()
{
isset(self::$instance) || self::$instance = new static;
return self::$instance;
}
/**
* @param WrapperInterface $wrapper
* @param string $slug
* @return $this
* @throws \Exception
*/
public static function add(WrapperInterface $wrapper, $slug = '')
{
$slug = $slug ?: $wrapper->getSlug();
if (self::instance()->exists($slug)) {
throw new \Exception("Wrapper $slug already exists.");
}
self::instance()->wrappers[$slug] = $wrapper;
return self::instance();
}
/**
* @param string $slug
* @return $this
*/
public static function remove($slug)
{
unset(self::instance()->wrappers[$slug]);
return self::instance();
}
/**
* @param string $slug
* @return null|WrapperInterface
*/
public static function get($slug)
{
return isset(self::instance()->wrappers[$slug]) ? self::instance()->wrappers[$slug] : null;
}
/**
* @return string[] Slugs of wrappers in collection
*/
public static function wrappers()
{
return array_keys(self::instance()->wrappers);
}
/**
* @param $slug
* @return bool
*/
public static function exists($slug)
{
return isset(self::instance()->wrappers[$slug]);
}
}

View File

@@ -13,15 +13,15 @@ interface WrapperInterface
* *
* @return string Wrapper template (FQPN of, e.g., `base-page.php`, `base.php`) * @return string Wrapper template (FQPN of, e.g., `base-page.php`, `base.php`)
*/ */
public function getWrapper(); public function wrap();
/** /**
* @return string Wrapped template (FQPN of, e.g., `page.php`, `single.php`, `singular.php`) * @return string Wrapped template (FQPN of, e.g., `page.php`, `single.php`, `singular.php`)
*/ */
public function getTemplate(); public function unwrap();
/** /**
* @return string Slug of the WrapperInterface; e.g., `base` * @return string Slug of the WrapperInterface; e.g., `base`
*/ */
public function getSlug(); public function slug();
} }

View File

@@ -14,11 +14,11 @@
<div class="wrap container" role="document"> <div class="wrap container" role="document">
<div class="content row"> <div class="content row">
<main class="main"> <main class="main">
<?php include App\template_unwrap(); ?> <?php include App\template()->main(); ?>
</main><!-- /.main --> </main><!-- /.main -->
<?php if (App\display_sidebar()) : ?> <?php if (App\display_sidebar()) : ?>
<aside class="sidebar"> <aside class="sidebar">
<?php get_template_part('partials/sidebar'); ?> <?php App\template_part('partials/sidebar'); ?>
</aside><!-- /.sidebar --> </aside><!-- /.sidebar -->
<?php endif; ?> <?php endif; ?>
</div><!-- /.content --> </div><!-- /.content -->