Merge branch 'master' of github.com:roots/sage
This commit is contained in:
24
app/admin.php
Normal file
24
app/admin.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
/**
|
||||
* Theme customizer
|
||||
*/
|
||||
add_action('customize_register', function (\WP_Customize_Manager $wp_customize) {
|
||||
// Add postMessage support
|
||||
$wp_customize->get_setting('blogname')->transport = 'postMessage';
|
||||
$wp_customize->selective_refresh->add_partial('blogname', [
|
||||
'selector' => '.brand',
|
||||
'render_callback' => function () {
|
||||
bloginfo('name');
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
/**
|
||||
* Customizer JS
|
||||
*/
|
||||
add_action('customize_preview_init', function () {
|
||||
wp_enqueue_script('sage/customizer.js', asset_path('scripts/customizer.js'), ['customize-preview'], null, true);
|
||||
});
|
||||
70
app/filters.php
Normal file
70
app/filters.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
/**
|
||||
* Add <body> classes
|
||||
*/
|
||||
add_filter('body_class', function (array $classes) {
|
||||
/** Add page slug if it doesn't exist */
|
||||
if (is_single() || is_page() && !is_front_page()) {
|
||||
if (!in_array(basename(get_permalink()), $classes)) {
|
||||
$classes[] = basename(get_permalink());
|
||||
}
|
||||
}
|
||||
|
||||
/** Add class if sidebar is active */
|
||||
if (display_sidebar()) {
|
||||
$classes[] = 'sidebar-primary';
|
||||
}
|
||||
|
||||
/** Clean up class names for custom templates */
|
||||
$classes = array_map(function ($class) {
|
||||
return preg_replace(['/-blade(-php)?$/', '/^page-template-views/'], '', $class);
|
||||
}, $classes);
|
||||
|
||||
return array_filter($classes);
|
||||
});
|
||||
|
||||
/**
|
||||
* Add "… Continued" to the excerpt
|
||||
*/
|
||||
add_filter('excerpt_more', function () {
|
||||
return ' … <a href="' . get_permalink() . '">' . __('Continued', 'sage') . '</a>';
|
||||
});
|
||||
|
||||
/**
|
||||
* Template Hierarchy should search for .blade.php files
|
||||
*/
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Render page using Blade
|
||||
*/
|
||||
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');
|
||||
}, PHP_INT_MAX);
|
||||
|
||||
/**
|
||||
* Tell WordPress how to find the compiled path of comments.blade.php
|
||||
*/
|
||||
add_filter('comments_template', 'App\\template_path');
|
||||
113
app/helpers.php
Normal file
113
app/helpers.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
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)
|
||||
*/
|
||||
function sage($abstract = null, $parameters = [], ContainerContract $container = null)
|
||||
{
|
||||
$container = $container ?: Container::getInstance();
|
||||
if (!$abstract) {
|
||||
return $container;
|
||||
}
|
||||
return $container->bound($abstract)
|
||||
? $container->makeWith($abstract, $parameters)
|
||||
: $container->makeWith("sage.{$abstract}", $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the specified configuration value.
|
||||
*
|
||||
* If an array is passed as the key, we will assume you want to set an array of values.
|
||||
*
|
||||
* @param array|string $key
|
||||
* @param mixed $default
|
||||
* @return mixed|\Roots\Sage\Config
|
||||
* @copyright Taylor Otwell
|
||||
* @link https://github.com/laravel/framework/blob/c0970285/src/Illuminate/Foundation/helpers.php#L254-L265
|
||||
*/
|
||||
function config($key = null, $default = null)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
return sage('config');
|
||||
}
|
||||
if (is_array($key)) {
|
||||
return sage('config')->set($key);
|
||||
}
|
||||
return sage('config')->get($key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
function template($file, $data = [])
|
||||
{
|
||||
return sage('blade')->render($file, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve path to a compiled blade view
|
||||
* @param $file
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
function template_path($file, $data = [])
|
||||
{
|
||||
return sage('blade')->compiledPath($file, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $asset
|
||||
* @return string
|
||||
*/
|
||||
function asset_path($asset)
|
||||
{
|
||||
return sage('assets')->getUri($asset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether to show the sidebar
|
||||
* @return bool
|
||||
*/
|
||||
function display_sidebar()
|
||||
{
|
||||
static $display;
|
||||
isset($display) || $display = apply_filters('sage/display_sidebar', false);
|
||||
return $display;
|
||||
}
|
||||
|
||||
/**
|
||||
* Page titles
|
||||
* @return string
|
||||
*/
|
||||
function title()
|
||||
{
|
||||
if (is_home()) {
|
||||
if ($home = get_option('page_for_posts', true)) {
|
||||
return get_the_title($home);
|
||||
}
|
||||
return __('Latest Posts', 'sage');
|
||||
}
|
||||
if (is_archive()) {
|
||||
return get_the_archive_title();
|
||||
}
|
||||
if (is_search()) {
|
||||
return sprintf(__('Search Results for %s', 'sage'), get_search_query());
|
||||
}
|
||||
if (is_404()) {
|
||||
return __('Not Found', 'sage');
|
||||
}
|
||||
return get_the_title();
|
||||
}
|
||||
41
app/lib/Sage/Assets/JsonManifest.php
Normal file
41
app/lib/Sage/Assets/JsonManifest.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?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)}";
|
||||
}
|
||||
}
|
||||
31
app/lib/Sage/Assets/ManifestInterface.php
Normal file
31
app/lib/Sage/Assets/ManifestInterface.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?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);
|
||||
}
|
||||
8
app/lib/Sage/Config.php
Normal file
8
app/lib/Sage/Config.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Roots\Sage;
|
||||
|
||||
class Config extends \Illuminate\Config\Repository
|
||||
{
|
||||
|
||||
}
|
||||
10
app/lib/Sage/Container.php
Normal file
10
app/lib/Sage/Container.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Roots\Sage;
|
||||
|
||||
use Illuminate\Container\Container as BaseContainer;
|
||||
|
||||
class Container extends BaseContainer
|
||||
{
|
||||
|
||||
}
|
||||
133
app/lib/Sage/PostCreateProject.php
Executable file
133
app/lib/Sage/PostCreateProject.php
Executable file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace Roots\Sage;
|
||||
|
||||
use Composer\Script\Event;
|
||||
|
||||
class PostCreateProject
|
||||
{
|
||||
public static function updateHeaders(Event $event)
|
||||
{
|
||||
// @codingStandardsIgnoreStart
|
||||
$io = $event->getIO();
|
||||
|
||||
if ($io->isInteractive()) {
|
||||
$io->write('<info>Define theme headers. Press enter key for default.</info>');
|
||||
|
||||
$theme_headers_default = [
|
||||
'name' => 'Sage Starter Theme',
|
||||
'uri' => 'https://roots.io/sage/',
|
||||
'description' => 'Sage is a WordPress starter theme.',
|
||||
'version' => '9.0.0-beta.3',
|
||||
'author' => 'Roots',
|
||||
'author_uri' => 'https://roots.io/'
|
||||
];
|
||||
$theme_headers = [
|
||||
'name' => $io->ask('<info>Theme Name [<comment>'.$theme_headers_default['name'].'</comment>]:</info> ', $theme_headers_default['name']),
|
||||
'uri' => $io->ask('<info>Theme URI [<comment>'.$theme_headers_default['uri'].'</comment>]:</info> ', $theme_headers_default['uri']),
|
||||
'description' => $io->ask('<info>Theme Description [<comment>'.$theme_headers_default['description'].'</comment>]:</info> ', $theme_headers_default['description']),
|
||||
'version' => $io->ask('<info>Theme Version [<comment>'.$theme_headers_default['version'].'</comment>]:</info> ', $theme_headers_default['version']),
|
||||
'author' => $io->ask('<info>Theme Author [<comment>'.$theme_headers_default['author'].'</comment>]:</info> ', $theme_headers_default['author']),
|
||||
'author_uri' => $io->ask('<info>Theme Author URI [<comment>'.$theme_headers_default['author_uri'].'</comment>]:</info> ', $theme_headers_default['author_uri'])
|
||||
];
|
||||
|
||||
file_put_contents('resources/style.css', str_replace($theme_headers_default, $theme_headers, file_get_contents('resources/style.css')));
|
||||
}
|
||||
}
|
||||
|
||||
public static function selectFramework(Event $event)
|
||||
{
|
||||
$io = $event->getIO();
|
||||
$default_framework_pattern = '"bootstrap": ".*"';
|
||||
|
||||
$files_to_clear = [
|
||||
'resources/assets/styles/components/_comments.scss',
|
||||
'resources/assets/styles/components/_forms.scss',
|
||||
'resources/assets/styles/components/_wp-classes.scss',
|
||||
'resources/assets/styles/layouts/_header.scss',
|
||||
];
|
||||
|
||||
|
||||
if ($io->isInteractive()) {
|
||||
$frameworks = [
|
||||
'Bootstrap',
|
||||
'Foundation',
|
||||
'Tachyons',
|
||||
'None'
|
||||
];
|
||||
$framework = $io->select('<info>Select a CSS framework</info> <comment>(Default: Bootstrap)</comment>', $frameworks, 0);
|
||||
|
||||
switch($framework) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
file_put_contents('package.json', preg_replace("/{$default_framework_pattern}/", '"foundation-sites": "6.3.0"', file_get_contents('package.json')));
|
||||
file_put_contents('resources/assets/styles/main.scss', str_replace('@import "~bootstrap/scss/bootstrap";' . "\n", '@import "~foundation-sites/scss/foundation";' . "\n" . '@include foundation-everything;' . "\n", file_get_contents('resources/assets/styles/main.scss')));
|
||||
file_put_contents('resources/assets/scripts/main.js', str_replace("import 'bootstrap';\n", "import 'foundation-sites/dist/js/foundation';\n", file_get_contents('resources/assets/scripts/main.js')));
|
||||
foreach($files_to_clear as $file) {
|
||||
file_put_contents($file, '');
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
file_put_contents('package.json', preg_replace("/{$default_framework_pattern}/", '"tachyons-sass": "^4.7.1"', file_get_contents('package.json')));
|
||||
file_put_contents('assets/styles/main.scss', str_replace('@import "~bootstrap/scss/bootstrap";' . "\n", '@import "~tachyons-sass/tachyons";' . "\n", file_get_contents('assets/styles/main.scss')));
|
||||
file_put_contents('assets/scripts/main.js', str_replace("import 'bootstrap';\n", '', file_get_contents('assets/scripts/main.js')));
|
||||
foreach($files_to_clear as $file) {
|
||||
file_put_contents($file, '');
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
file_put_contents('package.json', preg_replace("/\s+{$default_framework_pattern},/", '', file_get_contents('package.json')));
|
||||
file_put_contents('resources/assets/styles/main.scss', str_replace('@import "~bootstrap/scss/bootstrap";' . "\n", '', file_get_contents('resources/assets/styles/main.scss')));
|
||||
file_put_contents('resources/assets/scripts/main.js', str_replace("import 'bootstrap';\n", '', file_get_contents('resources/assets/scripts/main.js')));
|
||||
foreach($files_to_clear as $file) {
|
||||
file_put_contents($file, '');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function addFontAwesome(Event $event)
|
||||
{
|
||||
$io = $event->getIO();
|
||||
|
||||
if ($io->isInteractive()) {
|
||||
if ($io->askConfirmation('<info>Add Font Awesome?</info> [<comment>y,N</comment>]? ', false)) {
|
||||
$package = json_decode(file_get_contents('package.json'), true);
|
||||
$dependencies = $package['dependencies'];
|
||||
$dependencies = array_merge($dependencies, ['font-awesome' => '^4.7.0']);
|
||||
$package['dependencies'] = $dependencies;
|
||||
$package = str_replace(' ', ' ', json_encode($package, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n");
|
||||
file_put_contents('package.json', $package);
|
||||
|
||||
$import_dep_str = '// Import npm dependencies' . "\n";
|
||||
file_put_contents('resources/assets/styles/main.scss', str_replace($import_dep_str, $import_dep_str . '@import "~font-awesome/scss/font-awesome";' . "\n", file_get_contents('resources/assets/styles/main.scss')));
|
||||
file_put_contents('resources/assets/styles/common/_variables.scss', "\n" . '$fa-font-path: \'~font-awesome/fonts\';' . "\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function buildOptions(Event $event)
|
||||
{
|
||||
$io = $event->getIO();
|
||||
|
||||
if ($io->isInteractive()) {
|
||||
$io->write('<info>Configure build settings. Press enter key for default.</info>');
|
||||
|
||||
$browsersync_settings_default = [
|
||||
'publicPath' => '/app/themes/'.basename(getcwd()),
|
||||
'devUrl' => 'http://example.dev'
|
||||
];
|
||||
|
||||
$browsersync_settings = [
|
||||
'publicPath' => $io->ask('<info>Path to theme directory (eg. /wp-content/themes/sage) [<comment>'.$browsersync_settings_default['publicPath'].'</comment>]:</info> ', $browsersync_settings_default['publicPath']),
|
||||
'devUrl' => $io->ask('<info>Local development URL of WP site [<comment>'.$browsersync_settings_default['devUrl'].'</comment>]:</info> ', $browsersync_settings_default['devUrl'])
|
||||
];
|
||||
|
||||
file_put_contents('resources/assets/config.json', str_replace('/app/themes/sage', $browsersync_settings['publicPath'], file_get_contents('resources/assets/config.json')));
|
||||
file_put_contents('resources/assets/config.json', str_replace($browsersync_settings_default['devUrl'], $browsersync_settings['devUrl'], file_get_contents('resources/assets/config.json')));
|
||||
}
|
||||
}
|
||||
// @codingStandardsIgnoreEnd
|
||||
}
|
||||
129
app/lib/Sage/Template/Blade.php
Normal file
129
app/lib/Sage/Template/Blade.php
Normal file
@@ -0,0 +1,129 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
91
app/lib/Sage/Template/BladeProvider.php
Normal file
91
app/lib/Sage/Template/BladeProvider.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
40
app/lib/Sage/Template/FileViewFinder.php
Normal file
40
app/lib/Sage/Template/FileViewFinder.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?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));
|
||||
}
|
||||
}
|
||||
157
app/setup.php
Normal file
157
app/setup.php
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Contracts\Container\Container as ContainerContract;
|
||||
use Roots\Sage\Assets\JsonManifest;
|
||||
use Roots\Sage\Config;
|
||||
use Roots\Sage\Template\Blade;
|
||||
use Roots\Sage\Template\BladeProvider;
|
||||
|
||||
/**
|
||||
* Theme assets
|
||||
*/
|
||||
add_action('wp_enqueue_scripts', function () {
|
||||
wp_enqueue_style('sage/main.css', asset_path('styles/main.css'), false, null);
|
||||
wp_enqueue_script('sage/main.js', asset_path('scripts/main.js'), ['jquery'], null, true);
|
||||
}, 100);
|
||||
|
||||
/**
|
||||
* Theme setup
|
||||
*/
|
||||
add_action('after_setup_theme', function () {
|
||||
/**
|
||||
* Enable features from Soil when plugin is activated
|
||||
* @link https://roots.io/plugins/soil/
|
||||
*/
|
||||
add_theme_support('soil-clean-up');
|
||||
add_theme_support('soil-jquery-cdn');
|
||||
add_theme_support('soil-nav-walker');
|
||||
add_theme_support('soil-nice-search');
|
||||
add_theme_support('soil-relative-urls');
|
||||
|
||||
/**
|
||||
* Enable plugins to manage the document title
|
||||
* @link https://developer.wordpress.org/reference/functions/add_theme_support/#title-tag
|
||||
*/
|
||||
add_theme_support('title-tag');
|
||||
|
||||
/**
|
||||
* Register navigation menus
|
||||
* @link https://developer.wordpress.org/reference/functions/register_nav_menus/
|
||||
*/
|
||||
register_nav_menus([
|
||||
'primary_navigation' => __('Primary Navigation', 'sage')
|
||||
]);
|
||||
|
||||
/**
|
||||
* Enable post thumbnails
|
||||
* @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/
|
||||
*/
|
||||
add_theme_support('post-thumbnails');
|
||||
|
||||
/**
|
||||
* Enable HTML5 markup support
|
||||
* @link https://developer.wordpress.org/reference/functions/add_theme_support/#html5
|
||||
*/
|
||||
add_theme_support('html5', ['caption', 'comment-form', 'comment-list', 'gallery', 'search-form']);
|
||||
|
||||
/**
|
||||
* Enable selective refresh for widgets in customizer
|
||||
* @link https://developer.wordpress.org/themes/advanced-topics/customizer-api/#theme-support-in-sidebars
|
||||
*/
|
||||
add_theme_support('customize-selective-refresh-widgets');
|
||||
|
||||
/**
|
||||
* Use main stylesheet for visual editor
|
||||
* @see resources/assets/styles/layouts/_tinymce.scss
|
||||
*/
|
||||
add_editor_style(asset_path('styles/main.css'));
|
||||
}, 20);
|
||||
|
||||
/**
|
||||
* Register sidebars
|
||||
*/
|
||||
add_action('widgets_init', function () {
|
||||
$config = [
|
||||
'before_widget' => '<section class="widget %1$s %2$s">',
|
||||
'after_widget' => '</section>',
|
||||
'before_title' => '<h3>',
|
||||
'after_title' => '</h3>'
|
||||
];
|
||||
register_sidebar([
|
||||
'name' => __('Primary', 'sage'),
|
||||
'id' => 'sidebar-primary'
|
||||
] + $config);
|
||||
register_sidebar([
|
||||
'name' => __('Footer', 'sage'),
|
||||
'id' => 'sidebar-footer'
|
||||
] + $config);
|
||||
});
|
||||
|
||||
/**
|
||||
* Updates the `$post` variable on each iteration of the loop.
|
||||
* Note: updated value is only available for subsequently loaded views, such as partials
|
||||
*/
|
||||
add_action('the_post', function ($post) {
|
||||
sage('blade')->share('post', $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
|
||||
*/
|
||||
sage()->singleton('sage.assets', function () {
|
||||
return new JsonManifest(config('assets.manifest'), config('assets.uri'));
|
||||
});
|
||||
|
||||
/**
|
||||
* Add Blade to Sage container
|
||||
*/
|
||||
sage()->singleton('sage.blade', function (ContainerContract $app) {
|
||||
$cachePath = config('view.compiled');
|
||||
if (!file_exists($cachePath)) {
|
||||
wp_mkdir_p($cachePath);
|
||||
}
|
||||
(new BladeProvider($app))->register();
|
||||
return new Blade($app['view'], $app);
|
||||
});
|
||||
|
||||
/**
|
||||
* Create @asset() Blade directive
|
||||
*/
|
||||
sage('blade')->compiler()->directive('asset', function ($asset) {
|
||||
return "<?= App\\asset_path({$asset}); ?>";
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Init config
|
||||
*/
|
||||
sage()->bindIf('config', Config::class, true);
|
||||
Reference in New Issue
Block a user