Use roots/sage-lib (incl. new config system)

This commit is contained in:
2017-07-09 07:05:07 -07:00
parent 7a9d4f6be8
commit 1a8dce9b09
16 changed files with 626 additions and 806 deletions

View File

@@ -40,16 +40,7 @@ collect([
'index', '404', 'archive', 'author', 'category', 'tag', 'taxonomy', 'date', 'home',
'frontpage', 'page', 'paged', 'search', 'single', 'singular', 'attachment'
])->map(function ($type) {
add_filter("{$type}_template_hierarchy", function ($templates) {
return collect($templates)->flatMap(function ($template) {
$transforms = [
'%^/?(resources[\\/]views)?[\\/]?%' => '',
'%(\.blade)?(\.php)?$%' => ''
];
$normalizedTemplate = preg_replace(array_keys($transforms), array_values($transforms), $template);
return ["{$normalizedTemplate}.blade.php", "{$normalizedTemplate}.php"];
})->toArray();
});
add_filter("{$type}_template_hierarchy", __NAMESPACE__.'\\filter_templates');
});
/**
@@ -59,12 +50,21 @@ add_filter('template_include', function ($template) {
$data = collect(get_body_class())->reduce(function ($data, $class) use ($template) {
return apply_filters("sage/template/{$class}/data", $data, $template);
}, []);
echo template($template, $data);
// Return a blank file to make WordPress happy
return get_theme_file_path('index.php');
if ($template) {
echo template($template, $data);
return get_stylesheet_directory().'/index.php';
}
return $template;
}, PHP_INT_MAX);
/**
* Tell WordPress how to find the compiled path of comments.blade.php
*/
add_filter('comments_template', 'App\\template_path');
add_filter('comments_template', function ($comments_template) {
$comments_template = str_replace(
[get_stylesheet_directory(), get_template_directory()],
'',
$comments_template
);
return template_path(locate_template(["views/{$comments_template}", $comments_template]) ?: $comments_template);
});

View File

@@ -3,16 +3,14 @@
namespace App;
use Roots\Sage\Container;
use Illuminate\Contracts\Container\Container as ContainerContract;
/**
* Get the sage container.
*
* @param string $abstract
* @param array $parameters
* @param ContainerContract $container
* @return ContainerContract|mixed
* @SuppressWarnings(PHPMD.StaticAccess)
* @param Container $container
* @return Container|mixed
*/
function sage($abstract = null, $parameters = [], ContainerContract $container = null)
{
@@ -77,6 +75,42 @@ function asset_path($asset)
return sage('assets')->getUri($asset);
}
/**
* @param string|string[] $templates Possible template files
* @return array
*/
function filter_templates($templates)
{
return collect($templates)
->map(function ($template) {
return preg_replace('#\.(blade\.)?php$#', '', ltrim($template));
})
->flatMap(function ($template) {
$paths = apply_filters('sage/filter_templates/paths', ['views', 'resources/views']);
return collect($paths)
->flatMap(function ($path) use ($template) {
return [
"{$path}/{$template}.blade.php",
"{$path}/{$template}.php",
"{$template}.blade.php",
"{$template}.php",
];
});
})
->filter()
->unique()
->all();
}
/**
* @param string|string[] $templates Relative path to possible template files
* @return string Location of the template
*/
function locate_template($templates)
{
return \locate_template(filter_templates($templates));
}
/**
* Determine whether to show the sidebar
* @return bool

View File

@@ -1,41 +0,0 @@
<?php
namespace Roots\Sage\Assets;
/**
* Class JsonManifest
* @package Roots\Sage
* @author QWp6t
*/
class JsonManifest implements ManifestInterface
{
/** @var array */
public $manifest;
/** @var string */
public $dist;
/**
* JsonManifest constructor
*
* @param string $manifestPath Local filesystem path to JSON-encoded manifest
* @param string $distUri Remote URI to assets root
*/
public function __construct($manifestPath, $distUri)
{
$this->manifest = file_exists($manifestPath) ? json_decode(file_get_contents($manifestPath), true) : [];
$this->dist = $distUri;
}
/** @inheritdoc */
public function get($asset)
{
return isset($this->manifest[$asset]) ? $this->manifest[$asset] : $asset;
}
/** @inheritdoc */
public function getUri($asset)
{
return "{$this->dist}/{$this->get($asset)}";
}
}

View File

@@ -1,31 +0,0 @@
<?php
namespace Roots\Sage\Assets;
/**
* Interface ManifestInterface
* @package Roots\Sage
* @author QWp6t
*/
interface ManifestInterface
{
/**
* Get the cache-busted filename
*
* If the manifest does not have an entry for $asset, then return $asset
*
* @param string $asset The original name of the file before cache-busting
* @return string
*/
public function get($asset);
/**
* Get the cache-busted URI
*
* If the manifest does not have an entry for $asset, then return URI for $asset
*
* @param string $asset The original name of the file before cache-busting
* @return string
*/
public function getUri($asset);
}

View File

@@ -1,8 +0,0 @@
<?php
namespace Roots\Sage;
class Config extends \Illuminate\Config\Repository
{
}

View File

@@ -1,10 +0,0 @@
<?php
namespace Roots\Sage;
use Illuminate\Container\Container as BaseContainer;
class Container extends BaseContainer
{
}

View File

@@ -1,129 +0,0 @@
<?php
namespace Roots\Sage\Template;
use Illuminate\Contracts\Container\Container as ContainerContract;
use Illuminate\Contracts\View\Factory as FactoryContract;
use Illuminate\View\Engines\CompilerEngine;
use Illuminate\View\Engines\EngineInterface;
use Illuminate\View\ViewFinderInterface;
/**
* Class BladeProvider
* @method \Illuminate\View\View file($file, $data = [], $mergeData = [])
* @method \Illuminate\View\View make($file, $data = [], $mergeData = [])
*/
class Blade
{
/** @var ContainerContract */
protected $app;
public function __construct(FactoryContract $env, ContainerContract $app)
{
$this->env = $env;
$this->app = $app;
}
/**
* Get the compiler
*
* @return \Illuminate\View\Compilers\BladeCompiler
*/
public function compiler()
{
static $engineResolver;
if (!$engineResolver) {
$engineResolver = $this->app->make('view.engine.resolver');
}
return $engineResolver->resolve('blade')->getCompiler();
}
/**
* @param string $view
* @param array $data
* @param array $mergeData
* @return string
*/
public function render($view, $data = [], $mergeData = [])
{
/** @var \Illuminate\Contracts\Filesystem\Filesystem $filesystem */
$filesystem = $this->app['files'];
return $this->{$filesystem->exists($view) ? 'file' : 'make'}($view, $data, $mergeData)->render();
}
/**
* @param string $file
* @param array $data
* @param array $mergeData
* @return string
*/
public function compiledPath($file, $data = [], $mergeData = [])
{
$rendered = $this->file($file, $data, $mergeData);
/** @var EngineInterface $engine */
$engine = $rendered->getEngine();
if (!($engine instanceof CompilerEngine)) {
// Using PhpEngine, so just return the file
return $file;
}
$compiler = $engine->getCompiler();
$compiledPath = $compiler->getCompiledPath($rendered->getPath());
if ($compiler->isExpired($compiledPath)) {
$compiler->compile($file);
}
return $compiledPath;
}
/**
* @param string $file
* @return string
*/
public function normalizeViewPath($file)
{
// Convert `\` to `/`
$view = str_replace('\\', '/', $file);
// Add namespace to path if necessary
$view = $this->applyNamespaceToPath($view);
// Remove unnecessary parts of the path
$view = str_replace(array_merge($this->app['config']['view.paths'], ['.blade.php', '.php']), '', $view);
// Remove superfluous and leading slashes
return ltrim(preg_replace('%//+%', '/', $view), '/');
}
/**
* Convert path to view namespace
* @param string $path
* @return string
*/
public function applyNamespaceToPath($path)
{
/** @var ViewFinderInterface $finder */
$finder = $this->app['view.finder'];
if (!method_exists($finder, 'getHints')) {
return $path;
}
$delimiter = $finder::HINT_PATH_DELIMITER;
$hints = $finder->getHints();
$view = array_reduce(array_keys($hints), function ($view, $namespace) use ($delimiter, $hints) {
return str_replace($hints[$namespace], $namespace.$delimiter, $view);
}, $path);
return preg_replace("%{$delimiter}[\\/]*%", $delimiter, $view);
}
/**
* Pass any method to the view Factory instance.
*
* @param string $method
* @param array $params
* @return mixed
*/
public function __call($method, $params)
{
return call_user_func_array([$this->env, $method], $params);
}
}

View File

@@ -1,91 +0,0 @@
<?php
namespace Roots\Sage\Template;
use Illuminate\Container\Container;
use Illuminate\Contracts\Container\Container as ContainerContract;
use Illuminate\Events\Dispatcher;
use Illuminate\Filesystem\Filesystem;
use Illuminate\View\ViewServiceProvider;
/**
* Class BladeProvider
*/
class BladeProvider extends ViewServiceProvider
{
/**
* @param ContainerContract $container
* @param array $config
* @SuppressWarnings(PHPMD.StaticAccess)
*/
public function __construct(ContainerContract $container = null, $config = [])
{
/** @noinspection PhpParamsInspection */
parent::__construct($container ?: Container::getInstance());
$this->app->bindIf('config', function () use ($config) {
return $config;
}, true);
}
/**
* Bind required instances for the service provider.
*/
public function register()
{
$this->registerFilesystem();
$this->registerEvents();
$this->registerEngineResolver();
$this->registerViewFinder();
$this->registerFactory();
return $this;
}
/**
* Register Filesystem
*/
public function registerFilesystem()
{
$this->app->bindIf('files', Filesystem::class, true);
return $this;
}
/**
* Register the events dispatcher
*/
public function registerEvents()
{
$this->app->bindIf('events', Dispatcher::class, true);
return $this;
}
/** @inheritdoc */
public function registerEngineResolver()
{
parent::registerEngineResolver();
return $this;
}
/** @inheritdoc */
public function registerFactory()
{
parent::registerFactory();
return $this;
}
/**
* Register the view finder implementation.
*/
public function registerViewFinder()
{
$this->app->bindIf('view.finder', function ($app) {
$config = $this->app['config'];
$paths = $config['view.paths'];
$namespaces = $config['view.namespaces'];
$finder = new FileViewFinder($app['files'], $paths);
array_map([$finder, 'addNamespace'], array_keys($namespaces), $namespaces);
return $finder;
}, true);
return $this;
}
}

View File

@@ -1,40 +0,0 @@
<?php
namespace Roots\Sage\Template;
class FileViewFinder extends \Illuminate\View\FileViewFinder
{
const FALLBACK_PARTS_DELIMITER = '-';
/**
* Get an array of possible view files from a single file name.
*
* @param string $name
* @return array
*/
public function getPossibleViewFiles($name)
{
$parts = explode(self::FALLBACK_PARTS_DELIMITER, $name);
$templates[] = array_shift($parts);
foreach ($parts as $i => $part) {
$templates[] = $templates[$i].self::FALLBACK_PARTS_DELIMITER.$part;
}
rsort($templates);
return $this->getPossibleViewFilesFromTemplates($templates);
}
/**
* Get an array of possible view files from an array of templates
*
* @param array $templates
* @return array
*/
public function getPossibleViewFilesFromTemplates($templates)
{
return call_user_func_array('array_merge', array_map(function ($template) {
return array_map(function ($extension) use ($template) {
return str_replace('.', '/', $template).'.'.$extension;
}, $this->extensions);
}, $templates));
}
}

View File

@@ -2,9 +2,8 @@
namespace App;
use Illuminate\Contracts\Container\Container as ContainerContract;
use Roots\Sage\Container;
use Roots\Sage\Assets\JsonManifest;
use Roots\Sage\Config;
use Roots\Sage\Template\Blade;
use Roots\Sage\Template\BladeProvider;
@@ -101,29 +100,6 @@ add_action('the_post', function ($post) {
* Setup Sage options
*/
add_action('after_setup_theme', function () {
/**
* Sage config
*/
$paths = [
'dir.stylesheet' => get_stylesheet_directory(),
'dir.template' => get_template_directory(),
'dir.upload' => wp_upload_dir()['basedir'],
'uri.stylesheet' => get_stylesheet_directory_uri(),
'uri.template' => get_template_directory_uri(),
];
$viewPaths = collect(preg_replace('%[\/]?(resources/views)?[\/.]*?$%', '', [STYLESHEETPATH, TEMPLATEPATH]))
->flatMap(function ($path) {
return ["{$path}/resources/views", $path];
})->unique()->toArray();
config([
'assets.manifest' => "{$paths['dir.stylesheet']}/../dist/assets.json",
'assets.uri' => "{$paths['uri.stylesheet']}/dist",
'view.compiled' => "{$paths['dir.upload']}/cache/compiled",
'view.namespaces' => ['App' => WP_CONTENT_DIR],
'view.paths' => $viewPaths,
] + $paths);
/**
* Add JsonManifest to Sage container
*/
@@ -134,24 +110,19 @@ add_action('after_setup_theme', function () {
/**
* Add Blade to Sage container
*/
sage()->singleton('sage.blade', function (ContainerContract $app) {
sage()->singleton('sage.blade', function (Container $app) {
$cachePath = config('view.compiled');
if (!file_exists($cachePath)) {
wp_mkdir_p($cachePath);
}
(new BladeProvider($app))->register();
return new Blade($app['view'], $app);
return new Blade($app['view']);
});
/**
* Create @asset() Blade directive
*/
sage('blade')->compiler()->directive('asset', function ($asset) {
return "<?= App\\asset_path({$asset}); ?>";
return "<?= " . __NAMESPACE__ . "\\asset_path({$asset}); ?>";
});
});
/**
* Init config
*/
sage()->bindIf('config', Config::class, true);