diff --git a/src/.editorconfig b/src/.editorconfig new file mode 100644 index 0000000..0fa0fcd --- /dev/null +++ b/src/.editorconfig @@ -0,0 +1,6 @@ +# editorconfig.org + +root = false + +[*.php] +indent_size = 2 diff --git a/src/filters.php b/src/filters.php index 1577227..959b782 100644 --- a/src/filters.php +++ b/src/filters.php @@ -49,6 +49,5 @@ add_filter('template_include', function ($main) { if (!is_string($main) || !(string) $main) { return $main; } - $main = basename($main, '.php'); - return Template::wrap(new Wrapper($main, 'layouts/base.php'))->locate(); + return template_wrap(new Wrapper(basename($main))); }, 109); diff --git a/src/helpers.php b/src/helpers.php index 4a4f0cb..0ddea22 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -2,17 +2,16 @@ use Roots\Sage\Asset; use Roots\Sage\Assets\JsonManifest; -use Roots\Sage\Template; +use Roots\Sage\Template\WrapperCollection; +use Roots\Sage\Template\WrapperInterface; -/** - * @param string $slug - * @param array $context - */ -function template_unwrap($slug = '', $context = []) { - if ($file = Template::unwrap($slug, $context)->locate()) { - /** @noinspection PhpIncludeInspection */ - include $file; - } +function template_wrap(WrapperInterface $wrapper, $slug = 'base') { + WrapperCollection::add($wrapper, $slug); + return $wrapper->getWrapper(); +} + +function template_unwrap($slug = 'base') { + return WrapperCollection::get($slug)->getTemplate(); } /** diff --git a/src/lib/Sage/Template.php b/src/lib/Sage/Template.php deleted file mode 100644 index d94037f..0000000 --- a/src/lib/Sage/Template.php +++ /dev/null @@ -1,162 +0,0 @@ -getSlug()] = $wrapper; - return new static($wrapper->getWrappers(), $context); - } - - /** - * @param string $slug - * @param array $context - * @return static - */ - public static function unwrap($slug = '', $context = []) { - if (!$slug) { - // If no slug is specified, we grab the most recently wrapped item - end(self::$wrappers); - $slug = key(self::$wrappers); - } - - $template = new static(self::$wrappers[$slug]->getTemplate(), $context); - unset(self::$wrappers[$slug]); - return $template; - } - - /** - * Converts a delimeted template file into an array of parts - * - * Example: - * Template::getConvertedTemplateParts('content-single-audio.php'); - * => ['content-single-audio.php', 'content-single.php', 'content.php'] - * - * The returned value can then be passed to WordPress's locate_template. - * - * @param string $template - * @param string $delimeter - * @return array - */ - public static function convertParts($template, $delimeter = '-') { - $templateParts = explode($delimeter, str_replace('.php', '', (string) $template)); - $templates[] = array_shift($templateParts); - - foreach ($templateParts as $i => $templatePart) { - $templates[] = $templates[$i] . $delimeter . $templatePart; - } - - return array_reverse($templates); - } - - /** - * Template constructor - * @param string|string[] $template - * @param array $context - */ - public function __construct($template, array $context = []) { - $this->set($template); - $this->context = $context; - } - - /** - * @return string HTML - * @see get - */ - public function __toString() { - return $this->get(); - } - - /** - * Echoes the output HTML - * @see get - */ - public function render() { - echo $this->get(); - } - - /** - * @return string HTML - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ - public function get() { - /** @noinspection PhpUnusedLocalVariableInspection $context is passed to the included template */ - $context = $this->context; - extract($this->context); - ob_start(); - - if ($template = $this->locate()) { - /** @noinspection PhpIncludeInspection */ - include $template; - } - - $this->html = ob_get_clean() ?: ''; - return $this->html; - } - - /** - * @param string[]|string $template - */ - public function set($template) { - if (is_array($template)) { - $this->templates = self::format($template); - return; - } - - if (!is_string($template) || !(string) $template) { - return; - } - - // At this point, we assume it's something like `content-single.php` or `content-single-audio.php` - $this->templates = self::format(self::convertParts($template)); - } - - /** - * Ensures that each template in $this->templates is appended with `.php` - * @param $templates - * @return array - */ - protected static function format($templates) { - return array_map(function ($template) { - if (substr($template, -4, 4) === '.php') { - return $template; - } - - return $template . '.php'; - }, $templates); - } - - /** - * @param string $templateDir Specify a template directory relative to your theme directory; e.g., `templates/`, `templates/partials/`, `woocommerce/` - * @return string Filename - */ - public function locate($templateDir = '') { - $templates = array_map(function ($template) use ($templateDir) { - return ($templateDir ?: self::$root) . $template; - }, $this->templates); - - $template = locate_template($templates); - return apply_filters('sage/locate_template', $template, $templates) ?: $template; - } -} diff --git a/src/lib/Sage/Template/Wrapper.php b/src/lib/Sage/Template/Wrapper.php index 6e03fb6..c62bb58 100644 --- a/src/lib/Sage/Template/Wrapper.php +++ b/src/lib/Sage/Template/Wrapper.php @@ -13,26 +13,37 @@ class Wrapper implements WrapperInterface { protected $template = ''; /** @var string[] Array of template wrappers; e.g., `base-singular.php`, `base-page.php`, `base.php` */ - protected $wrappers = []; + protected $wrapper = []; + + /** @var string[] Cache template locations */ + protected static $locations = []; /** * Wrapper constructor * - * @param string $templateSlug Template slug, typically from Template Heirarchy; e.g., `page`, `single`, `singular` + * @param string $template Template file, as from Template Heirarchy; e.g., `page.php`, `single.php`, `singular.php` * @param string $base Wrapper's base template, this is what will wrap around $template */ - public function __construct($templateSlug, $base = 'layouts/base.php') { + public function __construct($template, $base = 'layouts/base.php') { $this->slug = sanitize_title(basename($base, '.php')); - $this->wrappers = [$base]; - $this->template = $templateSlug; + $this->wrapper = [$base]; + $this->template = $template; $str = substr($base, 0, -4); - array_unshift($this->wrappers, sprintf($str . '-%s.php', $templateSlug)); + array_unshift($this->wrapper, sprintf($str . '-%s.php', basename($template, '.php'))); + } + + /** + * @return string + * @see getTemplate + */ + public function __toString() { + return $this->getTemplate(); } /** {@inheritdoc} */ - public function getWrappers() { - $this->wrappers = apply_filters('sage/wrap_' . $this->slug, $this->wrappers) ?: $this->wrappers; - return $this->wrappers; + public function getWrapper() { + $wrappers = apply_filters('sage/wrap_' . $this->slug, $this->wrapper) ?: $this->wrapper; + return locate_template($wrappers); } /** {@inheritdoc} */ @@ -42,6 +53,7 @@ class Wrapper implements WrapperInterface { /** {@inheritdoc} */ public function getTemplate() { - return $this->template; + $template = apply_filters('sage/unwrap_' . $this->slug, $this->template) ?: $this->template; + return locate_template($template); } } diff --git a/src/lib/Sage/Template/WrapperCollection.php b/src/lib/Sage/Template/WrapperCollection.php new file mode 100644 index 0000000..b50fd75 --- /dev/null +++ b/src/lib/Sage/Template/WrapperCollection.php @@ -0,0 +1,73 @@ +getSlug(); + if (self::instance()->exists($slug) && !$overwriteIfExists) { + 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]); + } +} diff --git a/src/lib/Sage/Template/WrapperInterface.php b/src/lib/Sage/Template/WrapperInterface.php index 6a358eb..b94cf08 100644 --- a/src/lib/Sage/Template/WrapperInterface.php +++ b/src/lib/Sage/Template/WrapperInterface.php @@ -6,16 +6,16 @@ * @author QWp6t */ interface WrapperInterface { - /** - * Get a list of potential wrappers - * Useful for passing to WordPress's locate_template() - * - * @return string[] List of wrappers; e.g., `base-page.php`, `base.php` - */ - public function getWrappers(); /** - * @return string Template file that is being wrapped; e.g., `page.php`, `single.php`, `singular.php` + * Get wrapper template file + * + * @return string Wrapper template (FQPN of, e.g., `base-page.php`, `base.php`) + */ + public function getWrapper(); + + /** + * @return string Wrapped template (FQPN of, e.g., `page.php`, `single.php`, `singular.php`) */ public function getTemplate(); diff --git a/templates/layouts/base.php b/templates/layouts/base.php index e0c8bfe..7d7346e 100644 --- a/templates/layouts/base.php +++ b/templates/layouts/base.php @@ -14,7 +14,7 @@
- +