Restructure theme, use autoloader

This commit is contained in:
QWp6t
2015-12-18 16:41:37 -08:00
committed by Ben Word
parent 8d7bcee4c4
commit 9eaffa3a2d
47 changed files with 771 additions and 393 deletions

View File

@@ -23,9 +23,12 @@ install:
- composer self-update && composer --version
- export PATH="$HOME/.composer/vendor/bin:$PATH"
- composer global require squizlabs/php_codesniffer
- composer global require phpmd/phpmd
- composer install -o
script:
- npm run build
- npm run jshint
- npm run jscs
- phpcs --standard=ruleset.xml --extensions=php -n -s .
- phpcs --standard=ruleset.xml --extensions=php --ignore=node_modules,bower_components,vendor -n -s .
- phpmd app text cleancode,codesize,controversial,design,naming,unusedcode

15
app/admin.php Normal file
View File

@@ -0,0 +1,15 @@
<?php namespace App;
/**
* Add postMessage support
*/
add_action('customize_register', function (\WP_Customize_Manager $wp_customize) {
$wp_customize->get_setting('blogname')->transport = 'postMessage';
});
/**
* Customizer JS
*/
add_action('customize_preview_init', function () {
wp_enqueue_script('sage/customizer', asset_path('scripts/customizer.js'), ['customize-preview'], null, true);
});

55
app/filters.php Normal file
View File

@@ -0,0 +1,55 @@
<?php namespace App;
use Roots\Sage\Template;
use Roots\Sage\Template\Wrapper;
/**
* Determine which pages should NOT display the sidebar
* @link https://codex.wordpress.org/Conditional_Tags
*/
add_filter('sage/display_sidebar', function ($display) {
/** The sidebar will NOT be displayed if ANY of the following return true. */
return $display ? !in_array(true, [
is_404(),
is_front_page(),
is_page_template('template-custom.php'),
]) : $display;
});
/**
* 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';
}
return $classes;
});
/**
* Clean up the_excerpt()
*/
add_filter('excerpt_more', function () {
return ' &hellip; <a href="' . get_permalink() . '">' . __('Continued', 'sage') . '</a>';
});
/**
* Use Wrapper by default
*/
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();
}, 109);

77
app/helpers.php Normal file
View File

@@ -0,0 +1,77 @@
<?php namespace App;
use Roots\Sage\Asset;
use Roots\Sage\Assets\JsonManifest;
use Roots\Sage\Template;
/**
* @param string $slug
* @param array $context
*/
function template_unwrap($slug = '', $context = []) {
if ($file = Template::unwrap($slug, $context)->locate()) {
/** @noinspection PhpIncludeInspection */
include $file;
}
}
/**
* @param array $context
*/
function template_sidebar($context = []) {
template_part('sidebar', $context);
}
/**
* @param $template
* @param array $context
*/
function template_part($template, $context = []) {
if ($file = (new Template($template, $context))->locate()) {
/** @noinspection PhpIncludeInspection */
include $file;
}
}
/**
* @param $filename
* @return string
*/
function asset_path($filename) {
static $manifest;
isset($manifest) || $manifest = new JsonManifest(get_template_directory() . '/' . Asset::$dist . '/assets.json');
return (string) new Asset($filename, $manifest);
}
/**
* Determine whether to show the sidebar
* @return bool
*/
function display_sidebar() {
static $display;
isset($display) || $display = apply_filters('sage/display_sidebar', true);
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();
}

35
app/lib/Sage/Asset.php Normal file
View File

@@ -0,0 +1,35 @@
<?php namespace Roots\Sage;
use Roots\Sage\Assets\IManifest;
/**
* Class Template
* @package Roots\Sage
* @author QWp6t
*/
class Asset {
public static $dist = '/dist';
/** @var IManifest Currently used manifest */
protected $manifest;
protected $asset;
protected $dir;
public function __construct($file, IManifest $manifest = null) {
$this->manifest = $manifest;
$this->asset = basename($file);
$this->dir = dirname($file) != '.' ? dirname($file) : '';
}
public function __toString() {
return $this->getUri();
}
public function getUri() {
$file = self::$dist . '/' . $this->dir . '/' . ($this->manifest ? $this->manifest->get($this->asset) : $this->asset);
return get_template_directory_uri() . $file;
}
}

View File

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

View File

@@ -0,0 +1,29 @@
<?php namespace Roots\Sage\Assets;
/**
* Class JsonManifest
* @package Roots\Sage
* @author QWp6t
*/
class JsonManifest implements IManifest {
/** @var array */
protected $manifest = [];
/**
* JsonManifest constructor
* @param string $manifestPath Local filesystem path to JSON-encoded manifest
*/
public function __construct($manifestPath) {
$this->manifest = file_exists($manifestPath) ? json_decode(file_get_contents($manifestPath), true) : [];
}
/** @inheritdoc */
public function get($file) {
return isset($this->manifest[$file]) ? $this->manifest[$file] : $file;
}
/** @inheritdoc */
public function getAll() {
return $this->manifest;
}
}

151
app/lib/Sage/Template.php Normal file
View File

@@ -0,0 +1,151 @@
<?php namespace Roots\Sage;
use Roots\Sage\Template\IWrapper;
/**
* Class Template
* @package Roots\Sage
* @author QWp6t
*/
class Template {
protected static $root = 'templates/';
/** @var IWrapper[] */
protected static $wrappers = [];
protected $templates = [];
protected $context = [];
protected $html = '';
/**
* @param IWrapper $wrapper
* @param array $context Variables to pass to wrapper
* @return static Template instance of wrapper
*/
public static function wrap(IWrapper $wrapper, $context = []) {
self::$wrappers[$wrapper->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);
}
return new static(self::$wrappers[$slug]->getTemplate(), $context);
}
/**
* 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;
}
}

View File

@@ -0,0 +1,27 @@
<?php namespace Roots\Sage\Template;
/**
* Interface IWrapper
* @package Roots\Sage
* @author QWp6t
*/
interface IWrapper {
/**
* 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`
*/
public function getTemplate();
/**
* @return string Slug of the Wrapper; e.g., `base`
*/
public function getSlug();
}

View File

@@ -0,0 +1,48 @@
<?php namespace Roots\Sage\Template;
/**
* Interface Wrapper
* @package Roots\Sage
* @author QWp6t
*/
class Wrapper implements IWrapper {
/** @var string Wrapper slug */
protected $slug;
/** @var string Template file that is being wrapped */
protected $template = '';
/** @var string[] Array of template wrappers; e.g., `base-singular.php`, `base-page.php`, `base.php` */
protected $wrappers = [];
/**
* Wrapper constructor
*
* @param string $templateSlug Template slug, typically from Template Heirarchy; e.g., `page`, `single`, `singular`
* @param string $base Wrapper's base template, this is what will wrap around $template
*/
public function __construct($templateSlug, $base = 'layouts/base.php') {
$this->slug = sanitize_title(basename($base, '.php'));
$this->wrappers = [$base];
$this->template = $templateSlug;
$str = substr($base, 0, -4);
array_unshift($this->wrappers, sprintf($str . '-%s.php', $templateSlug));
}
/** {@inheritdoc} */
public function getWrappers() {
$this->wrappers = apply_filters('sage/wrap_' . $this->slug, $this->wrappers) ?: $this->wrappers;
return $this->wrappers;
}
/** {@inheritdoc} */
public function getSlug() {
return $this->slug;
}
/** {@inheritdoc} */
public function getTemplate()
{
return $this->template;
}
}

96
app/setup.php Normal file
View File

@@ -0,0 +1,96 @@
<?php namespace App;
use Roots\Sage\Template;
/**
* 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');
/**
* Make theme available for translation
* @link https://github.com/roots/sage-translations Community translations
*/
load_theme_textdomain('sage', get_template_directory() . '/lang');
/**
* Enable plugins to manage the document title
* @link http://codex.wordpress.org/Function_Reference/add_theme_support#Title_Tag
*/
add_theme_support('title-tag');
/**
* Register wp_nav_menu() menus
* @link http://codex.wordpress.org/Function_Reference/register_nav_menus
*/
register_nav_menus([
'primary_navigation' => __('Primary Navigation', 'sage')
]);
/**
* Enable post thumbnails
* @link http://codex.wordpress.org/Post_Thumbnails
* @link http://codex.wordpress.org/Function_Reference/set_post_thumbnail_size
* @link http://codex.wordpress.org/Function_Reference/add_image_size
*/
add_theme_support('post-thumbnails');
/**
* Enable post formats
* @link http://codex.wordpress.org/Post_Formats
*/
add_theme_support('post-formats', ['aside', 'gallery', 'link', 'image', 'quote', 'video', 'audio']);
/**
* Enable HTML5 markup support
* @link http://codex.wordpress.org/Function_Reference/add_theme_support#HTML5
*/
add_theme_support('html5', ['caption', 'comment-form', 'comment-list', 'gallery', 'search-form']);
/**
* Use main stylesheet for visual editor
* @see /assets/styles/layouts/_tinymce.scss
*/
add_editor_style(asset_path('styles/main.css'));
});
/**
* Register sidebars
*/
add_action('widgets_init', function () {
$config = function ($name, $id = '') {
return [
'name' => __($name, 'sage'),
'id' => 'sidebar-' . $id ?: sanitize_title($name),
'before_widget' => '<section class="widget %1$s %2$s">',
'after_widget' => '</section>',
'before_title' => '<h3>',
'after_title' => '</h3>'
];
};
register_sidebar($config('Primary'));
register_sidebar($config('Footer'));
});
/**
* Theme assets
*/
add_action('wp_enqueue_scripts', function () {
wp_enqueue_style('sage/css', asset_path('styles/main.css'), false, null);
if (is_single() && comments_open() && get_option('thread_comments')) {
wp_enqueue_script('comment-reply');
}
wp_enqueue_script('sage/js', asset_path('scripts/main.js'), ['jquery'], null, true);
}, 100);

View File

@@ -23,8 +23,19 @@
"issues": "https://github.com/roots/sage/issues",
"forum": "https://discourse.roots.io/"
},
"autoload": {
"psr-4": {
"Roots\\Sage\\": "app/lib/Sage/"
},
"files": [
"app/helpers.php",
"app/setup.php",
"app/filters.php",
"app/admin.php"
]
},
"require": {
"php": ">=5.4.0",
"php": ">=5.5.0",
"composer/installers": "~1.0"
}
}

119
composer.lock generated Normal file
View File

@@ -0,0 +1,119 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "85f4aee59d18d093f8e3a52b8a70f766",
"content-hash": "75ad99c892e1d82404c58fe3bd989585",
"packages": [
{
"name": "composer/installers",
"version": "v1.0.22",
"source": {
"type": "git",
"url": "https://github.com/composer/installers.git",
"reference": "bd9b14f094c89c8b5804a4e41edeb7853bb85046"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/installers/zipball/bd9b14f094c89c8b5804a4e41edeb7853bb85046",
"reference": "bd9b14f094c89c8b5804a4e41edeb7853bb85046",
"shasum": ""
},
"require": {
"composer-plugin-api": "1.0.0"
},
"replace": {
"roundcube/plugin-installer": "*",
"shama/baton": "*"
},
"require-dev": {
"composer/composer": "1.0.*@dev",
"phpunit/phpunit": "4.1.*"
},
"type": "composer-plugin",
"extra": {
"class": "Composer\\Installers\\Plugin",
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-0": {
"Composer\\Installers\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Kyle Robinson Young",
"email": "kyle@dontkry.com",
"homepage": "https://github.com/shama"
}
],
"description": "A multi-framework Composer library installer",
"homepage": "http://composer.github.com/installers/",
"keywords": [
"Craft",
"Dolibarr",
"Hurad",
"MODX Evo",
"OXID",
"SMF",
"Thelia",
"WolfCMS",
"agl",
"aimeos",
"annotatecms",
"bitrix",
"cakephp",
"chef",
"codeigniter",
"concrete5",
"croogo",
"dokuwiki",
"drupal",
"elgg",
"fuelphp",
"grav",
"installer",
"joomla",
"kohana",
"laravel",
"lithium",
"magento",
"mako",
"mediawiki",
"modulework",
"moodle",
"phpbb",
"piwik",
"ppi",
"puppet",
"roundcube",
"shopware",
"silverstripe",
"symfony",
"typo3",
"wordpress",
"zend",
"zikula"
],
"time": "2015-10-29 23:28:48"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=5.5.0"
},
"platform-dev": []
}

View File

@@ -1,28 +1,28 @@
<?php
/**
* Sage includes
*
* The $sage_includes array determines the code library included in your theme.
* Add or remove files to the array as needed. Supports child theme overrides.
*
* Please note that missing files will produce a fatal error.
*
* @link https://github.com/roots/sage/pull/1042
* Do not edit anything in this file unless you know what you're doing
*/
$sage_includes = [
'lib/assets.php', // Scripts and stylesheets
'lib/extras.php', // Custom functions
'lib/setup.php', // Theme setup
'lib/titles.php', // Page titles
'lib/wrapper.php', // Theme wrapper class
'lib/customizer.php' // Theme customizer
];
foreach ($sage_includes as $file) {
if (!$filepath = locate_template($file)) {
trigger_error(sprintf(__('Error locating %s for inclusion', 'sage'), $file), E_USER_ERROR);
}
/**
* Here's what's happening with these hooks:
* 1. WordPress detects theme in themes/sage
* 2. When we activate, we tell WordPress that the theme is actually in themes/sage/templates
* 3. When we call get_template_directory() or get_template_directory_uri(), we point it back to themes/sage
*
* We do this so that the Template Hierarchy will look in themes/sage/templates for core WordPress themes
* But functions.php, style.css, and index.php are all still located in themes/sage
*
* themes/sage/index.php also contains some self-correcting code, just in case the template option gets reset
*/
add_filter('template', function ($template) {
return dirname($template);
});
add_action('after_switch_theme', function () {
update_option('template', get_option('template') . '/templates');
});
require_once $filepath;
}
unset($file, $filepath);
/**
* Require composer autoloader
*/
require_once __DIR__ . '/vendor/autoload.php';

View File

@@ -244,7 +244,7 @@ gulp.task('clean', require('del').bind(null, [path.dist]));
// See: http://www.browsersync.io
gulp.task('watch', function() {
browserSync.init({
files: ['{lib,templates}/**/*.php', '*.php'],
files: ['{app,templates}/**/*.php'],
proxy: config.devUrl,
snippetOptions: {
whitelist: ['/wp-admin/admin-ajax.php'],

View File

@@ -1,14 +1,6 @@
<?php get_template_part('templates/page', 'header'); ?>
<?php
<?php if (!have_posts()) : ?>
<div class="alert alert-warning">
<?php _e('Sorry, no results were found.', 'sage'); ?>
</div>
<?php get_search_form(); ?>
<?php endif; ?>
<?php while (have_posts()) : the_post(); ?>
<?php get_template_part('templates/content', get_post_type() != 'post' ? get_post_type() : get_post_format()); ?>
<?php endwhile; ?>
<?php the_posts_navigation(); ?>
if (defined('ABSPATH')) {
update_option('template', get_option('template') . '/templates');
}
die("Kind Regards,\nRoots");

View File

@@ -1,58 +0,0 @@
<?php
namespace Roots\Sage\Assets;
/**
* Get paths for assets
*/
class JsonManifest {
private $manifest;
public function __construct($manifest_path) {
if (file_exists($manifest_path)) {
$this->manifest = json_decode(file_get_contents($manifest_path), true);
} else {
$this->manifest = [];
}
}
public function get() {
return $this->manifest;
}
public function getPath($key = '', $default = null) {
$collection = $this->manifest;
if (is_null($key)) {
return $collection;
}
if (isset($collection[$key])) {
return $collection[$key];
}
foreach (explode('.', $key) as $segment) {
if (!isset($collection[$segment])) {
return $default;
} else {
$collection = $collection[$segment];
}
}
return $collection;
}
}
function asset_path($filename) {
$dist_path = get_template_directory_uri() . '/dist/';
$directory = dirname($filename) . '/';
$file = basename($filename);
static $manifest;
if (empty($manifest)) {
$manifest_path = get_template_directory() . '/dist/' . 'assets.json';
$manifest = new JsonManifest($manifest_path);
}
if (array_key_exists($file, $manifest->get())) {
return $dist_path . $directory . $manifest->get()[$file];
} else {
return $dist_path . $directory . $file;
}
}

View File

@@ -1,21 +0,0 @@
<?php
namespace Roots\Sage\Customizer;
use Roots\Sage\Assets;
/**
* Add postMessage support
*/
function customize_register($wp_customize) {
$wp_customize->get_setting('blogname')->transport = 'postMessage';
}
add_action('customize_register', __NAMESPACE__ . '\\customize_register');
/**
* Customizer JS
*/
function customize_preview_js() {
wp_enqueue_script('sage/customizer', Assets\asset_path('scripts/customizer.js'), ['customize-preview'], null, true);
}
add_action('customize_preview_init', __NAMESPACE__ . '\\customize_preview_js');

View File

@@ -1,33 +0,0 @@
<?php
namespace Roots\Sage\Extras;
use Roots\Sage\Setup;
/**
* Add <body> classes
*/
function body_class($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 (Setup\display_sidebar()) {
$classes[] = 'sidebar-primary';
}
return $classes;
}
add_filter('body_class', __NAMESPACE__ . '\\body_class');
/**
* Clean up the_excerpt()
*/
function excerpt_more() {
return ' &hellip; <a href="' . get_permalink() . '">' . __('Continued', 'sage') . '</a>';
}
add_filter('excerpt_more', __NAMESPACE__ . '\\excerpt_more');

View File

@@ -1,106 +0,0 @@
<?php
namespace Roots\Sage\Setup;
use Roots\Sage\Assets;
/**
* Theme setup
*/
function setup() {
// Enable features from Soil when plugin is activated
// https://roots.io/plugins/soil/
add_theme_support('soil-clean-up');
add_theme_support('soil-nav-walker');
add_theme_support('soil-nice-search');
add_theme_support('soil-jquery-cdn');
add_theme_support('soil-relative-urls');
// Make theme available for translation
// Community translations can be found at https://github.com/roots/sage-translations
load_theme_textdomain('sage', get_template_directory() . '/lang');
// Enable plugins to manage the document title
// http://codex.wordpress.org/Function_Reference/add_theme_support#Title_Tag
add_theme_support('title-tag');
// Register wp_nav_menu() menus
// http://codex.wordpress.org/Function_Reference/register_nav_menus
register_nav_menus([
'primary_navigation' => __('Primary Navigation', 'sage')
]);
// Enable post thumbnails
// http://codex.wordpress.org/Post_Thumbnails
// http://codex.wordpress.org/Function_Reference/set_post_thumbnail_size
// http://codex.wordpress.org/Function_Reference/add_image_size
add_theme_support('post-thumbnails');
// Enable post formats
// http://codex.wordpress.org/Post_Formats
add_theme_support('post-formats', ['aside', 'gallery', 'link', 'image', 'quote', 'video', 'audio']);
// Enable HTML5 markup support
// http://codex.wordpress.org/Function_Reference/add_theme_support#HTML5
add_theme_support('html5', ['caption', 'comment-form', 'comment-list', 'gallery', 'search-form']);
// Use main stylesheet for visual editor
// To add custom styles edit /assets/styles/layouts/_tinymce.scss
add_editor_style(Assets\asset_path('styles/main.css'));
}
add_action('after_setup_theme', __NAMESPACE__ . '\\setup');
/**
* Register sidebars
*/
function widgets_init() {
register_sidebar([
'name' => __('Primary', 'sage'),
'id' => 'sidebar-primary',
'before_widget' => '<section class="widget %1$s %2$s">',
'after_widget' => '</section>',
'before_title' => '<h3>',
'after_title' => '</h3>'
]);
register_sidebar([
'name' => __('Footer', 'sage'),
'id' => 'sidebar-footer',
'before_widget' => '<section class="widget %1$s %2$s">',
'after_widget' => '</section>',
'before_title' => '<h3>',
'after_title' => '</h3>'
]);
}
add_action('widgets_init', __NAMESPACE__ . '\\widgets_init');
/**
* Determine which pages should NOT display the sidebar
*/
function display_sidebar() {
static $display;
isset($display) || $display = !in_array(true, [
// The sidebar will NOT be displayed if ANY of the following return true.
// @link https://codex.wordpress.org/Conditional_Tags
is_404(),
is_front_page(),
is_page_template('template-custom.php'),
]);
return apply_filters('sage/display_sidebar', $display);
}
/**
* Theme assets
*/
function assets() {
wp_enqueue_style('sage/css', Assets\asset_path('styles/main.css'), false, null);
if (is_single() && comments_open() && get_option('thread_comments')) {
wp_enqueue_script('comment-reply');
}
wp_enqueue_script('sage/js', Assets\asset_path('scripts/main.js'), ['jquery'], null, true);
}
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\\assets', 100);

View File

@@ -1,24 +0,0 @@
<?php
namespace Roots\Sage\Titles;
/**
* Page titles
*/
function title() {
if (is_home()) {
if (get_option('page_for_posts', true)) {
return get_the_title(get_option('page_for_posts', true));
} else {
return __('Latest Posts', 'sage');
}
} elseif (is_archive()) {
return get_the_archive_title();
} elseif (is_search()) {
return sprintf(__('Search Results for %s', 'sage'), get_search_query());
} elseif (is_404()) {
return __('Not Found', 'sage');
} else {
return get_the_title();
}
}

View File

@@ -1,64 +0,0 @@
<?php
namespace Roots\Sage\Wrapper;
/**
* Theme wrapper
*
* @link https://roots.io/sage/docs/theme-wrapper/
* @link http://scribu.net/wordpress/theme-wrappers.html
*/
function template_path() {
return SageWrapping::$main_template;
}
function sidebar_path() {
return new SageWrapping('templates/sidebar.php');
}
class SageWrapping {
// Stores the full path to the main template file
public static $main_template;
// Basename of template file
public $slug;
// Array of templates
public $templates;
// Stores the base name of the template file; e.g. 'page' for 'page.php' etc.
public static $base;
public function __construct($template = 'base.php') {
$this->slug = basename($template, '.php');
$this->templates = [$template];
if (self::$base) {
$str = substr($template, 0, -4);
array_unshift($this->templates, sprintf($str . '-%s.php', self::$base));
}
}
public function __toString() {
$this->templates = apply_filters('sage/wrap_' . $this->slug, $this->templates);
return locate_template($this->templates);
}
public static function wrap($main) {
// Check for other filters returning null
if (!is_string($main)) {
return $main;
}
self::$main_template = $main;
self::$base = basename(self::$main_template, '.php');
if (self::$base === 'index') {
self::$base = false;
}
return new SageWrapping();
}
}
add_filter('template_include', [__NAMESPACE__ . '\\SageWrapping', 'wrap'], 109);

View File

@@ -1,6 +1,6 @@
{
"name": "sage",
"version": "8.4.2",
"version": "9.0.0",
"author": "Ben Word <ben@benword.com>",
"homepage": "https://roots.io/sage/",
"private": true,

View File

@@ -1,4 +0,0 @@
<?php while (have_posts()) : the_post(); ?>
<?php get_template_part('templates/page', 'header'); ?>
<?php get_template_part('templates/content', 'page'); ?>
<?php endwhile; ?>

View File

@@ -28,11 +28,6 @@
<!-- Allow PHP closing tags on templates -->
<rule ref="PSR2.Files.ClosingTag.NotAllowed">
<exclude-pattern>templates/*</exclude-pattern>
<exclude-pattern>404.php</exclude-pattern>
<exclude-pattern>index.php</exclude-pattern>
<exclude-pattern>page.php</exclude-pattern>
<exclude-pattern>single.php</exclude-pattern>
<exclude-pattern>template-custom.php</exclude-pattern>
</rule>
<!-- Force 2 spaces indentation -->

View File

@@ -1 +0,0 @@
<?php get_template_part('templates/content-single', get_post_type()); ?>

View File

@@ -2,7 +2,7 @@
Theme Name: Sage Starter Theme
Theme URI: https://roots.io/sage/
Description: Sage is a WordPress starter theme. <a href="https://github.com/roots/sage">Contribute on GitHub</a>
Version: 8.4.2
Version: 9.0.0
Author: Roots
Author URI: https://roots.io/
Text Domain: sage

View File

@@ -1,10 +0,0 @@
<?php
/**
* Template Name: Custom Template
*/
?>
<?php while (have_posts()) : the_post(); ?>
<?php get_template_part('templates/page', 'header'); ?>
<?php get_template_part('templates/content', 'page'); ?>
<?php endwhile; ?>

View File

@@ -1,4 +1,4 @@
<?php get_template_part('templates/page', 'header'); ?>
<?php App\template_part('partials/page-header'); ?>
<div class="alert alert-warning">
<?php _e('Sorry, but the page you were trying to view does not exist.', 'sage'); ?>

14
templates/index.php Normal file
View File

@@ -0,0 +1,14 @@
<?php App\template_part('partials/page-header'); ?>
<?php if (!have_posts()) : ?>
<div class="alert alert-warning">
<?php _e('Sorry, no results were found.', 'sage'); ?>
</div>
<?php get_search_form(); ?>
<?php endif; ?>
<?php while (have_posts()) : the_post(); ?>
<?php App\template_part('partials/content-' . (get_post_type() != 'post' ? get_post_type() : get_post_format())); ?>
<?php endwhile; ?>
<?php the_posts_navigation(); ?>

View File

@@ -1,13 +1,6 @@
<?php
use Roots\Sage\Setup;
use Roots\Sage\Wrapper;
?>
<!doctype html>
<html <?php language_attributes(); ?>>
<?php get_template_part('templates/head'); ?>
<?php App\template_part('partials/head'); ?>
<body <?php body_class(); ?>>
<!--[if IE]>
<div class="alert alert-warning">
@@ -16,23 +9,23 @@ use Roots\Sage\Wrapper;
<![endif]-->
<?php
do_action('get_header');
get_template_part('templates/header');
App\template_part('partials/header');
?>
<div class="wrap container" role="document">
<div class="content row">
<main class="main">
<?php include Wrapper\template_path(); ?>
<?php App\template_unwrap(); ?>
</main><!-- /.main -->
<?php if (Setup\display_sidebar()) : ?>
<?php if (App\display_sidebar()) : ?>
<aside class="sidebar">
<?php include Wrapper\sidebar_path(); ?>
<?php App\template_sidebar(); ?>
</aside><!-- /.sidebar -->
<?php endif; ?>
</div><!-- /.content -->
</div><!-- /.wrap -->
<?php
do_action('get_footer');
get_template_part('templates/footer');
App\template_part('partials/footer');
wp_footer();
?>
</body>

View File

@@ -1,5 +0,0 @@
<?php use Roots\Sage\Titles; ?>
<div class="page-header">
<h1><?= Titles\title(); ?></h1>
</div>

4
templates/page.php Normal file
View File

@@ -0,0 +1,4 @@
<?php while (have_posts()) : the_post(); ?>
<?php App\template_part('partials/page-header'); ?>
<?php App\template_part('partials/content-page'); ?>
<?php endwhile; ?>

View File

@@ -1,7 +1,7 @@
<article <?php post_class(); ?>>
<header>
<h2 class="entry-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<?php if (get_post_type() === 'post') { get_template_part('templates/entry-meta'); } ?>
<?php if (get_post_type() === 'post') { App\template_part('partials/entry-meta'); } ?>
</header>
<div class="entry-summary">
<?php the_excerpt(); ?>

View File

@@ -2,7 +2,7 @@
<article <?php post_class(); ?>>
<header>
<h1 class="entry-title"><?php the_title(); ?></h1>
<?php get_template_part('templates/entry-meta'); ?>
<?php App\template_part('partials/entry-meta'); ?>
</header>
<div class="entry-content">
<?php the_content(); ?>
@@ -10,6 +10,6 @@
<footer>
<?php wp_link_pages(['before' => '<nav class="page-nav"><p>' . __('Pages:', 'sage'), 'after' => '</p></nav>']); ?>
</footer>
<?php comments_template('/templates/comments.php'); ?>
<?php comments_template('/templates/partials/comments.php'); ?>
</article>
<?php endwhile; ?>

View File

@@ -1,7 +1,7 @@
<article <?php post_class(); ?>>
<header>
<h2 class="entry-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<?php get_template_part('templates/entry-meta'); ?>
<?php App\template_part('partials/entry-meta'); ?>
</header>
<div class="entry-summary">
<?php the_excerpt(); ?>

View File

@@ -0,0 +1,3 @@
<div class="page-header">
<h1><?php App\title(); ?></h1>
</div>

View File

@@ -1,4 +1,4 @@
<?php get_template_part('templates/page', 'header'); ?>
<?php App\template_part('partials/header-page'); ?>
<?php if (!have_posts()) : ?>
<div class="alert alert-warning">
@@ -8,7 +8,7 @@
<?php endif; ?>
<?php while (have_posts()) : the_post(); ?>
<?php get_template_part('templates/content', 'search'); ?>
<?php App\template_part('partials/content-search'); ?>
<?php endwhile; ?>
<?php the_posts_navigation(); ?>

1
templates/single.php Normal file
View File

@@ -0,0 +1 @@
<?php App\template_part('partials/content-single-' . get_post_type()); ?>

View File

@@ -0,0 +1,10 @@
<?php
/**
* Template Name: Custom Template
*/
?>
<?php while (have_posts()) : the_post(); ?>
<?php App\template_part('partials/page-header'); ?>
<?php App\template_part('partials/content-page'); ?>
<?php endwhile; ?>