Merge pull request #1251 from roots/8.0.0

Sage 8.0.0
This commit is contained in:
Ben Word
2015-02-25 10:04:55 -06:00
71 changed files with 1421 additions and 2131 deletions

View File

@@ -1,3 +1,3 @@
{
"directory": "assets/vendor"
"directory": "bower_components"
}

9
.gitignore vendored
View File

@@ -1,9 +1,6 @@
# Include your project-specific ignores in this file
# Read about how to use .gitignore: https://help.github.com/articles/ignoring-files
dist
bower_components
node_modules
assets/vendor/*
assets/css/main.css.map
assets/css/*main*.css
assets/js/*scripts*.js
assets/js/vendor/modernizr.min.js
assets/manifest.json
npm-debug.log

95
.jscsrc Normal file
View File

@@ -0,0 +1,95 @@
{
"requireCurlyBraces": [
"if",
"else",
"for",
"while",
"do",
"try",
"catch"
],
"requireOperatorBeforeLineBreak": true,
"requireCamelCaseOrUpperCaseIdentifiers": true,
"maximumLineLength": {
"value": 80,
"allowComments": true,
"allowRegex": true
},
"validateIndentation": 2,
"validateQuoteMarks": "'",
"disallowMultipleLineStrings": true,
"disallowMixedSpacesAndTabs": true,
"disallowTrailingWhitespace": true,
"disallowSpaceAfterPrefixUnaryOperators": true,
"disallowMultipleVarDecl": true,
"disallowKeywordsOnNewLine": [
"else"
],
"requireSpaceAfterKeywords": [
"if",
"else",
"for",
"while",
"do",
"switch",
"return",
"try",
"catch"
],
"requireSpaceBeforeBinaryOperators": [
"=",
"+=",
"-=",
"*=",
"/=",
"%=",
"<<=",
">>=",
">>>=",
"&=",
"|=",
"^=",
"+=",
"+",
"-",
"*",
"/",
"%",
"<<",
">>",
">>>",
"&",
"|",
"^",
"&&",
"||",
"===",
"==",
">=",
"<=",
"<",
">",
"!=",
"!=="
],
"requireSpaceAfterBinaryOperators": true,
"requireSpacesInConditionalExpression": true,
"requireSpaceBeforeBlockStatements": true,
"requireSpacesInForStatement": true,
"requireLineFeedAtFileEnd": true,
"requireSpacesInFunctionExpression": {
"beforeOpeningCurlyBrace": true
},
"disallowSpacesInAnonymousFunctionExpression": {
"beforeOpeningRoundBrace": true
},
"disallowSpacesInsideObjectBrackets": "all",
"disallowSpacesInsideArrayBrackets": "all",
"disallowSpacesInsideParentheses": true,
"validateJSDoc": {
"checkParamNames": true,
"requireParamTypes": true
},
"disallowMultipleLineBreaks": true,
"disallowNewlineBeforeBlockStatements": true
}

View File

@@ -11,6 +11,5 @@
"newcap": true,
"noarg": true,
"node": true,
"strict": false,
"trailing": true
"strict": false
}

19
.travis.yml Normal file
View File

@@ -0,0 +1,19 @@
sudo: false
language: php
php:
- '5.6'
- '5.5'
- '5.4'
before_install:
- npm install -g npm@latest
- npm install -g bower gulp jscs
- npm install
- pyrus install pear/PHP_CodeSniffer
- phpenv rehash
script:
- npm run build
- npm run jshint
- npm run jscs
- phpcs --standard=ruleset.xml --extensions=php -n -s .

View File

@@ -1,13 +1,7 @@
<?php get_template_part('templates/page', 'header'); ?>
<div class="alert alert-warning">
<?php _e('Sorry, but the page you were trying to view does not exist.', 'roots'); ?>
<?php _e('Sorry, but the page you were trying to view does not exist.', 'sage'); ?>
</div>
<p><?php _e('It looks like this was the result of either:', 'roots'); ?></p>
<ul>
<li><?php _e('a mistyped address', 'roots'); ?></li>
<li><?php _e('an out-of-date link', 'roots'); ?></li>
</ul>
<?php get_search_form(); ?>

View File

@@ -1,3 +1,28 @@
### 8.0.0: February 25th, 2015
* Change theme name from Roots to Sage
* Bump required PHP version to >=5.4
* Add coding standards based on PSR-2
* Add Travis CI
* Add namespace
* Use short array syntax
* Use short echo syntax
* Switch from Grunt to gulp, new front-end development workflow
* Switch from Livereload to [BrowserSync](http://www.browsersync.io/)
* Use wiredep for Sass and Less injection
* Implement JSON file based asset pipeline with [asset-builder](https://github.com/austinpray/asset-builder)
* Re-organize asset file structure
* Re-organize stylesheet file structure
* Add main.scss.example and instructions for using Sass
* Use the primary theme stylesheet for the editor stylesheet
* Remove theme activation, move to [wp-cli-theme-activation](https://github.com/roots/wp-cli-theme-activation)
* Simplify 404 page
* Convert Sidebar to ConditionalTagCheck
* Update to jQuery 1.11.2
* Use new core navigation template tag
* Update sidebar to fix default template check
* Update nav walker to correctly assign `active` classes for custom post types
* Better support for CPT templates
### 7.0.3: December 18th, 2014
* Use `get_the_archive_title`
* Remove `wp_title`, add title-tag theme support

View File

@@ -1,121 +1 @@
# Contributing to Roots Theme
Please take a moment to review this document in order to make the contribution
process easy and effective for everyone involved.
Following these guidelines helps to communicate that you respect the time of
the developers managing and developing this open source project. In return,
they should reciprocate that respect in addressing your issue or assessing
patches and features.
## Using the issue tracker
The issue tracker is the preferred channel for [bug reports](#bugs),
[features requests](#features) and [submitting pull
requests](#pull-requests), but please respect the following restrictions:
* Please **do not** use the issue tracker for personal support requests (use the
[Roots Discourse](http://discourse.roots.io/)).
* Please **do not** derail or troll issues. Keep the discussion on topic and
respect the opinions of others.
<a name="bugs"></a>
## Bug reports
A bug is a _demonstrable problem_ that is caused by the code in the repository.
Good bug reports are extremely helpful - thank you!
Guidelines for bug reports:
1. **Use the GitHub issue search** &mdash; check if the issue has already been
reported.
2. **Check if the issue has been fixed** &mdash; try to reproduce it using the
latest `master` or development branch in the repository.
3. **Isolate the problem to Roots** &mdash; make sure that the code in the Roots
repository is _definitely_ responsible for the issue. Switch to a core WordPress
theme (such as Twenty Thirteen) to confirm problems before reporting an issue.
Make sure you have reproduced the bug with all plugins disabled. Any issues
related to HTML5 Boilerplate or Bootstrap should be reported to their respected
repositories and follow their contributing guidelines.
A good bug report shouldn't leave others needing to chase you up for more
information. Please try to be as detailed as possible in your report.
<a name="features"></a>
## Feature requests
Feature requests are welcome. But take a moment to find out whether your idea
fits with the scope and aims of Roots. It's up to *you* to make a strong
case to convince the Roots developers of the merits of this feature. Please
provide as much detail and context as possible.
<a name="pull-requests"></a>
## Pull requests
Good pull requests - patches, improvements, new features - are a fantastic
help. They should remain focused in scope and avoid containing unrelated
commits.
**Please ask first** before embarking on any significant pull request (e.g.
implementing features, refactoring code), otherwise you risk spending a lot of
time working on something that the developers might not want to merge into Roots.
Please adhere to the coding conventions used throughout the project (indentation,
comments, etc.).
Adhering to the following this process is the best way to get your work
included in Roots:
1. [Fork](http://help.github.com/fork-a-repo/) Roots, clone your fork,
and configure the remotes:
```bash
# Clone your fork of the repo into the current directory
git clone https://github.com/<your-username>/<repo-name>
# Navigate to the newly cloned directory
cd <repo-name>
# Assign the original repo to a remote called "upstream"
git remote add upstream https://github.com/<upsteam-owner>/<repo-name>
```
2. If you cloned a while ago, get the latest changes from upstream:
```bash
git checkout <dev-branch>
git pull upstream <dev-branch>
```
3. Create a new topic branch (off the main project development branch) to
contain your feature, change, or fix:
```bash
git checkout -b <topic-branch-name>
```
4. Commit your changes in logical chunks. Please adhere to these [git commit
message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
or your code is unlikely be merged into the main project. Use Git's
[interactive rebase](https://help.github.com/articles/interactive-rebase)
feature to tidy up your commits before making them public.
5. Locally merge (or rebase) the upstream development branch into your topic branch:
```bash
git pull [--rebase] upstream <dev-branch>
```
6. Push your topic branch up to your fork:
```bash
git push origin <topic-branch-name>
```
10. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/)
with a clear title and description.
Please read [Contributing to Roots Projects](https://github.com/roots/guidelines/blob/master/CONTRIBUTING.md)

View File

@@ -1,178 +0,0 @@
'use strict';
module.exports = function(grunt) {
// Load all tasks
require('load-grunt-tasks')(grunt);
// Show elapsed time
require('time-grunt')(grunt);
var jsFileList = [
'assets/vendor/bootstrap/js/transition.js',
'assets/vendor/bootstrap/js/alert.js',
'assets/vendor/bootstrap/js/button.js',
'assets/vendor/bootstrap/js/carousel.js',
'assets/vendor/bootstrap/js/collapse.js',
'assets/vendor/bootstrap/js/dropdown.js',
'assets/vendor/bootstrap/js/modal.js',
'assets/vendor/bootstrap/js/tooltip.js',
'assets/vendor/bootstrap/js/popover.js',
'assets/vendor/bootstrap/js/scrollspy.js',
'assets/vendor/bootstrap/js/tab.js',
'assets/vendor/bootstrap/js/affix.js',
'assets/js/plugins/*.js',
'assets/js/_*.js'
];
grunt.initConfig({
jshint: {
options: {
jshintrc: '.jshintrc'
},
all: [
'Gruntfile.js',
'assets/js/*.js',
'!assets/js/scripts.js',
'!assets/**/*.min.*'
]
},
less: {
dev: {
files: {
'assets/css/main.css': [
'assets/less/main.less'
]
},
options: {
compress: false,
// LESS source map
// To enable, set sourceMap to true and update sourceMapRootpath based on your install
sourceMap: true,
sourceMapFilename: 'assets/css/main.css.map',
sourceMapRootpath: '/app/themes/roots/'
}
},
build: {
files: {
'assets/css/main.min.css': [
'assets/less/main.less'
]
},
options: {
compress: true
}
}
},
concat: {
options: {
separator: ';',
},
dist: {
src: [jsFileList],
dest: 'assets/js/scripts.js',
},
},
uglify: {
dist: {
files: {
'assets/js/scripts.min.js': [jsFileList]
}
}
},
autoprefixer: {
options: {
browsers: ['last 2 versions', 'ie 8', 'ie 9', 'android 2.3', 'android 4', 'opera 12']
},
dev: {
options: {
map: {
prev: 'assets/css/'
}
},
src: 'assets/css/main.css'
},
build: {
src: 'assets/css/main.min.css'
}
},
modernizr: {
build: {
devFile: 'assets/vendor/modernizr/modernizr.js',
outputFile: 'assets/js/vendor/modernizr.min.js',
files: {
'src': [
['assets/js/scripts.min.js'],
['assets/css/main.min.css']
]
},
extra: {
shiv: false
},
uglify: true,
parseFiles: true
}
},
version: {
default: {
options: {
format: true,
length: 32,
manifest: 'assets/manifest.json',
querystring: {
style: 'roots_css',
script: 'roots_js'
}
},
files: {
'lib/scripts.php': 'assets/{css,js}/{main,scripts}.min.{css,js}'
}
}
},
watch: {
less: {
files: [
'assets/less/*.less',
'assets/less/**/*.less'
],
tasks: ['less:dev', 'autoprefixer:dev']
},
js: {
files: [
jsFileList,
'<%= jshint.all %>'
],
tasks: ['jshint', 'concat']
},
livereload: {
// Browser live reloading
// https://github.com/gruntjs/grunt-contrib-watch#live-reloading
options: {
livereload: false
},
files: [
'assets/css/main.css',
'assets/js/scripts.js',
'templates/*.php',
'*.php'
]
}
}
});
// Register tasks
grunt.registerTask('default', [
'dev'
]);
grunt.registerTask('dev', [
'jshint',
'less:dev',
'autoprefixer:dev',
'concat'
]);
grunt.registerTask('build', [
'jshint',
'less:build',
'autoprefixer:build',
'uglify',
'modernizr',
'version'
]);
};

View File

@@ -1,43 +1,50 @@
# [Roots Starter Theme](http://roots.io/)
[![devDependency Status](https://david-dm.org/roots/roots/dev-status.svg)](https://david-dm.org/roots/roots#info=devDependencies)
# [Sage](https://roots.io/sage/)
[![Build Status](https://travis-ci.org/roots/sage.svg)](https://travis-ci.org/roots/sage)
[![devDependency Status](https://david-dm.org/roots/sage/dev-status.svg)](https://david-dm.org/roots/sage#info=devDependencies)
Roots is a WordPress starter theme based on [HTML5 Boilerplate](http://html5boilerplate.com/) & [Bootstrap](http://getbootstrap.com/) that will help you make better themes.
Sage is a WordPress starter theme based on HTML5 Boilerplate, gulp, Bower, and Bootstrap, that will help you make better themes.
* Source: [https://github.com/roots/roots](https://github.com/roots/roots)
* Homepage: [http://roots.io/](http://roots.io/)
* Documentation: [http://roots.io/docs/](http://roots.io/docs/)
* Twitter: [@rootswp](https://twitter.com/rootswp), [@retlehs](https://twitter.com/retlehs), [@swalkinshaw](https://twitter.com/swalkinshaw), [@Foxaii](https://twitter.com/Foxaii), [@c2foryou](https://twitter.com/c2foryou)
* Source: [https://github.com/roots/sage](https://github.com/roots/sage)
* Homepage: [https://roots.io/sage/](https://roots.io/sage/)
* Documentation: [https://roots.io/sage/docs/](https://roots.io/sage/docs/)
* Twitter: [@rootswp](https://twitter.com/rootswp), [@retlehs](https://twitter.com/retlehs), [@swalkinshaw](https://twitter.com/swalkinshaw), [@Foxaii](https://twitter.com/Foxaii), [@c2foryou](https://twitter.com/c2foryou), [@austinpray](https://twitter.com/austinpray)
* Newsletter: [Subscribe](http://roots.io/subscribe/)
* Forum: [http://discourse.roots.io/](http://discourse.roots.io/)
* Forum: [https://discourse.roots.io/](https://discourse.roots.io/)
## Requirements
* PHP >= 5.4
* Node.js >= 0.10
* npm >= 2.1.5 (`npm install -g npm@latest`)
* gulp (`npm install -g gulp`)
* Bower (`npm install -g bower`)
## Features
* [Grunt](http://roots.io/using-grunt-for-wordpress-theme-development/) for compiling LESS to CSS, checking for JS errors, live reloading, concatenating and minifying files, versioning assets, and generating lean Modernizr builds
* [gulp](http://gulpjs.com/) build script that compiles both Less and Sass, checks for JavaScript errors, optimizes images, and concatenates and minifies files
* [BrowserSync](http://www.browsersync.io/) for keeping multiple browsers and devices synchronized while testing, along with injecting updated CSS and JS into your browser while you're developing
* [Bower](http://bower.io/) for front-end package management
* [asset-builder](https://github.com/austinpray/asset-builder) for the JSON file based asset pipeline
* [Bootstrap](http://getbootstrap.com/)
* [Theme wrapper](https://roots.io/sage/docs/theme-wrapper/)
* [HTML5 Boilerplate](http://html5boilerplate.com/)
* The latest [jQuery](http://jquery.com/) via Google CDN, with a local fallback
* The latest [Modernizr](http://modernizr.com/) build for feature detection, with lean builds with Grunt
* The latest [Modernizr](http://modernizr.com/) build for feature detection
* An optimized Google Analytics snippet
* [Bootstrap](http://getbootstrap.com/)
* Organized file and template structure
* ARIA roles and microformats
* [Theme activation](http://roots.io/roots-101/#theme-activation)
* [Theme wrapper](http://roots.io/an-introduction-to-the-roots-theme-wrapper/)
* Cleaner HTML output of navigation menus
* Posts use the [hNews](http://microformats.org/wiki/hnews) microformat
* [Multilingual ready](http://roots.io/wpml/) and over 30 available [community translations](https://github.com/roots/roots-translations)
### Additional features
* [Multilingual ready](https://roots.io/wpml/) and over 30 available [community translations](https://github.com/roots/sage-translations)
Install the [Soil](https://github.com/roots/soil) plugin to enable additional features:
* Cleaner output of `wp_head` and enqueued assets
* Root relative URLs
* Nice search (`/search/query/`)
* Cleaner output of `wp_head` and enqueued assets markup
## Installation
Clone the git repo - `git clone git://github.com/roots/roots.git` - or [download it](https://github.com/roots/roots/zipball/master) and then rename the directory to the name of your theme or website.
Clone the git repo - `git clone https://github.com/roots/sage.git` and then rename the directory to the name of your theme or website.
If you don't use [Bedrock](https://github.com/roots/bedrock), you'll need to add the following to your `wp-config.php` on your development installation:
@@ -45,10 +52,6 @@ If you don't use [Bedrock](https://github.com/roots/bedrock), you'll need to add
define('WP_ENV', 'development');
```
## Theme activation
Reference the [theme activation](http://roots.io/roots-101/#theme-activation) documentation to understand everything that happens once you activate Roots.
## Configuration
Edit `lib/config.php` to enable or disable theme features and to define a Google Analytics ID.
@@ -57,49 +60,41 @@ Edit `lib/init.php` to setup navigation menus, post thumbnail sizes, post format
## Theme development
Roots uses [Grunt](http://gruntjs.com/) for compiling LESS to CSS, checking for JS errors, live reloading, concatenating and minifying files, versioning assets, and generating lean Modernizr builds.
Sage uses [gulp](http://gulpjs.com/) as its build system and [Bower](http://bower.io/) to manage front-end packages.
If you'd like to use Bootstrap Sass, look at the [Roots Sass](https://github.com/roots/roots-sass) fork.
### Install gulp and Bower
### Install Grunt and Bower
**Unfamiliar with npm? Don't have node installed?** [Download and install node.js](http://nodejs.org/download/) before proceeding.
Building the theme requires [node.js](http://nodejs.org/download/). We recommend you update to the latest version of npm: `npm install -g npm@latest`.
From the command line:
1. Install `grunt-cli` and `bower` globally with `npm install -g grunt-cli bower`.
2. Navigate to the theme directory, then run `npm install`. npm will look at `package.json` and automatically install the necessary dependencies. It will also automatically run `bower install`, which installs front-end packages defined in `bower.json`.
1. Install [gulp](http://gulpjs.com) and [Bower](http://bower.io/) globally with `npm install -g gulp bower`
2. Navigate to the theme directory, then run `npm install`
3. Run `bower install`
When completed, you'll be able to run the various Grunt commands provided from the command line.
You now have all the necessary dependencies to run the build process.
**N.B.**
You will need write permission to the global npm directory to install `grunt-cli` and `bower`. You will also likely have to be using an elevated terminal or prefix the command with `sudo`, i.e., `sudo npm install -g grunt-cli bower`.
### Available gulp commands
We also advise against running as root user. NPM deliberately uses limited privileges when executing certain commands such as those included in the Roots post-install process, and when this happens to the root user, any file system objects that are not expressly writable by the root user will fail to write during the execution of the command. These might include directories such as `/var/www` or `/home/someotheruser`. If you're running as root and have problems, don't say we didn't warn you.
* `gulp` — Compile and optimize the files in your assets directory
* `gulp watch` — Compile assets when file changes are made
* `gulp --production` — Compile assets for production (no source maps).
### Available Grunt commands
* `grunt dev` — Compile LESS to CSS, concatenate and validate JS
* `grunt watch` — Compile assets when file changes are made
* `grunt build` — Create minified assets that are used on non-development environments
To use BrowserSync during `gulp watch` you need update `devUrl` at the bottom of `assets/manifest.json` to reflect your local development hostname.
## Documentation
* [Roots 101](http://roots.io/roots-101/) — A guide to installing Roots, the files, and theme organization
* [Theme Wrapper](http://roots.io/an-introduction-to-the-roots-theme-wrapper/) — Learn all about the theme wrapper
* [Build Script](http://roots.io/using-grunt-for-wordpress-theme-development/) — A look into how Roots uses Grunt
* [Roots Sidebar](http://roots.io/the-roots-sidebar/) — Understand how to display or hide the sidebar in Roots
Sage documentation is available at [https://roots.io/sage/docs/](https://roots.io/sage/docs/).
## Contributing
Everyone is welcome to help [contribute](CONTRIBUTING.md) and improve this project. There are several ways you can contribute:
Contributions are welcome from everyone. We have [contributing guidelines](CONTRIBUTING.md) to help you get started.
* Reporting issues (please read [issue guidelines](https://github.com/necolas/issue-guidelines))
* Suggesting new features
* Writing or refactoring code
* Fixing [issues](https://github.com/roots/roots/issues)
* Replying to questions on the [forum](http://discourse.roots.io/)
## Community
## Support
Keep track of development and community news.
Use the [Roots Discourse](http://discourse.roots.io/) to ask questions and get support.
* Participate on the [Roots Discourse](https://discourse.roots.io/)
* Follow [@rootswp on Twitter](https://twitter.com/rootswp)
* Read and subscribe to the [Roots Blog](https://roots.io/blog/)
* Subscribe to the [Roots Newsletter](https://roots.io/subscribe/)

View File

@@ -1,687 +0,0 @@
/**
* Updating this file with Bootstrap changes:
*
* 1. Go to http://getbootstrap.com/customize/
* 2. Un-toggle everything
* 3. Check: 'Typography'
* 4. Download
* 5. Remove margin property on body tag
*/
html {
font-family: sans-serif;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
nav,
section,
summary {
display: block;
}
audio,
canvas,
progress,
video {
display: inline-block;
vertical-align: baseline;
}
audio:not([controls]) {
display: none;
height: 0;
}
[hidden],
template {
display: none;
}
a {
background: transparent;
}
a:active,
a:hover {
outline: 0;
}
abbr[title] {
border-bottom: 1px dotted;
}
b,
strong {
font-weight: bold;
}
dfn {
font-style: italic;
}
h1 {
font-size: 2em;
margin: 0.67em 0;
}
mark {
background: #ff0;
color: #000;
}
small {
font-size: 80%;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
img {
border: 0;
}
svg:not(:root) {
overflow: hidden;
}
figure {
margin: 1em 40px;
}
hr {
-moz-box-sizing: content-box;
box-sizing: content-box;
height: 0;
}
pre {
overflow: auto;
}
code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
button,
input,
optgroup,
select,
textarea {
color: inherit;
font: inherit;
margin: 0;
}
button {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
html input[type="button"],
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button;
cursor: pointer;
}
button[disabled],
html input[disabled] {
cursor: default;
}
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
input {
line-height: normal;
}
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box;
padding: 0;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
height: auto;
}
input[type="search"] {
-webkit-appearance: textfield;
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box;
box-sizing: content-box;
}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
legend {
border: 0;
padding: 0;
}
textarea {
overflow: auto;
}
optgroup {
font-weight: bold;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
td,
th {
padding: 0;
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html {
font-size: 10px;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 1.42857143;
color: #333333;
background-color: #ffffff;
}
input,
button,
select,
textarea {
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
a {
color: #428bca;
text-decoration: none;
}
a:hover,
a:focus {
color: #2a6496;
text-decoration: underline;
}
a:focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
figure {
margin: 0;
}
img {
vertical-align: middle;
}
.img-responsive {
display: block;
width: 100% \9;
max-width: 100%;
height: auto;
}
.img-rounded {
border-radius: 6px;
}
.img-thumbnail {
padding: 4px;
line-height: 1.42857143;
background-color: #ffffff;
border: 1px solid #dddddd;
border-radius: 4px;
-webkit-transition: all 0.2s ease-in-out;
-o-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
display: inline-block;
width: 100% \9;
max-width: 100%;
height: auto;
}
.img-circle {
border-radius: 50%;
}
hr {
margin-top: 20px;
margin-bottom: 20px;
border: 0;
border-top: 1px solid #eeeeee;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
.sr-only-focusable:active,
.sr-only-focusable:focus {
position: static;
width: auto;
height: auto;
margin: 0;
overflow: visible;
clip: auto;
}
h1,
h2,
h3,
h4,
h5,
h6,
.h1,
.h2,
.h3,
.h4,
.h5,
.h6 {
font-family: inherit;
font-weight: 500;
line-height: 1.1;
color: inherit;
}
h1 small,
h2 small,
h3 small,
h4 small,
h5 small,
h6 small,
.h1 small,
.h2 small,
.h3 small,
.h4 small,
.h5 small,
.h6 small,
h1 .small,
h2 .small,
h3 .small,
h4 .small,
h5 .small,
h6 .small,
.h1 .small,
.h2 .small,
.h3 .small,
.h4 .small,
.h5 .small,
.h6 .small {
font-weight: normal;
line-height: 1;
color: #777777;
}
h1,
.h1,
h2,
.h2,
h3,
.h3 {
margin-top: 20px;
margin-bottom: 10px;
}
h1 small,
.h1 small,
h2 small,
.h2 small,
h3 small,
.h3 small,
h1 .small,
.h1 .small,
h2 .small,
.h2 .small,
h3 .small,
.h3 .small {
font-size: 65%;
}
h4,
.h4,
h5,
.h5,
h6,
.h6 {
margin-top: 10px;
margin-bottom: 10px;
}
h4 small,
.h4 small,
h5 small,
.h5 small,
h6 small,
.h6 small,
h4 .small,
.h4 .small,
h5 .small,
.h5 .small,
h6 .small,
.h6 .small {
font-size: 75%;
}
h1,
.h1 {
font-size: 36px;
}
h2,
.h2 {
font-size: 30px;
}
h3,
.h3 {
font-size: 24px;
}
h4,
.h4 {
font-size: 18px;
}
h5,
.h5 {
font-size: 14px;
}
h6,
.h6 {
font-size: 12px;
}
p {
margin: 0 0 10px;
}
.lead {
margin-bottom: 20px;
font-size: 16px;
font-weight: 300;
line-height: 1.4;
}
@media (min-width: 768px) {
.lead {
font-size: 21px;
}
}
small,
.small {
font-size: 85%;
}
cite {
font-style: normal;
}
mark,
.mark {
background-color: #fcf8e3;
padding: .2em;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.text-center {
text-align: center;
}
.text-justify {
text-align: justify;
}
.text-nowrap {
white-space: nowrap;
}
.text-lowercase {
text-transform: lowercase;
}
.text-uppercase {
text-transform: uppercase;
}
.text-capitalize {
text-transform: capitalize;
}
.text-muted {
color: #777777;
}
.text-primary {
color: #428bca;
}
a.text-primary:hover {
color: #3071a9;
}
.text-success {
color: #3c763d;
}
a.text-success:hover {
color: #2b542c;
}
.text-info {
color: #31708f;
}
a.text-info:hover {
color: #245269;
}
.text-warning {
color: #8a6d3b;
}
a.text-warning:hover {
color: #66512c;
}
.text-danger {
color: #a94442;
}
a.text-danger:hover {
color: #843534;
}
.bg-primary {
color: #fff;
background-color: #428bca;
}
a.bg-primary:hover {
background-color: #3071a9;
}
.bg-success {
background-color: #dff0d8;
}
a.bg-success:hover {
background-color: #c1e2b3;
}
.bg-info {
background-color: #d9edf7;
}
a.bg-info:hover {
background-color: #afd9ee;
}
.bg-warning {
background-color: #fcf8e3;
}
a.bg-warning:hover {
background-color: #f7ecb5;
}
.bg-danger {
background-color: #f2dede;
}
a.bg-danger:hover {
background-color: #e4b9b9;
}
.page-header {
padding-bottom: 9px;
margin: 40px 0 20px;
border-bottom: 1px solid #eeeeee;
}
ul,
ol {
margin-top: 0;
margin-bottom: 10px;
}
ul ul,
ol ul,
ul ol,
ol ol {
margin-bottom: 0;
}
.list-unstyled {
padding-left: 0;
list-style: none;
}
.list-inline {
padding-left: 0;
list-style: none;
margin-left: -5px;
}
.list-inline > li {
display: inline-block;
padding-left: 5px;
padding-right: 5px;
}
dl {
margin-top: 0;
margin-bottom: 20px;
}
dt,
dd {
line-height: 1.42857143;
}
dt {
font-weight: bold;
}
dd {
margin-left: 0;
}
@media (min-width: 768px) {
.dl-horizontal dt {
float: left;
width: 160px;
clear: left;
text-align: right;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dl-horizontal dd {
margin-left: 180px;
}
}
abbr[title],
abbr[data-original-title] {
cursor: help;
border-bottom: 1px dotted #777777;
}
.initialism {
font-size: 90%;
text-transform: uppercase;
}
blockquote {
padding: 10px 20px;
margin: 0 0 20px;
font-size: 17.5px;
border-left: 5px solid #eeeeee;
}
blockquote p:last-child,
blockquote ul:last-child,
blockquote ol:last-child {
margin-bottom: 0;
}
blockquote footer,
blockquote small,
blockquote .small {
display: block;
font-size: 80%;
line-height: 1.42857143;
color: #777777;
}
blockquote footer:before,
blockquote small:before,
blockquote .small:before {
content: '\2014 \00A0';
}
.blockquote-reverse,
blockquote.pull-right {
padding-right: 15px;
padding-left: 0;
border-right: 5px solid #eeeeee;
border-left: 0;
text-align: right;
}
.blockquote-reverse footer:before,
blockquote.pull-right footer:before,
.blockquote-reverse small:before,
blockquote.pull-right small:before,
.blockquote-reverse .small:before,
blockquote.pull-right .small:before {
content: '';
}
.blockquote-reverse footer:after,
blockquote.pull-right footer:after,
.blockquote-reverse small:after,
blockquote.pull-right small:after,
.blockquote-reverse .small:after,
blockquote.pull-right .small:after {
content: '\00A0 \2014';
}
blockquote:before,
blockquote:after {
content: "";
}
address {
margin-bottom: 20px;
font-style: normal;
line-height: 1.42857143;
}
.clearfix:before,
.clearfix:after,
.dl-horizontal dd:before,
.dl-horizontal dd:after {
content: " ";
display: table;
}
.clearfix:after,
.dl-horizontal dd:after {
clear: both;
}
.center-block {
display: block;
margin-left: auto;
margin-right: auto;
}
.pull-right {
float: right !important;
}
.pull-left {
float: left !important;
}
.hide {
display: none !important;
}
.show {
display: block !important;
}
.invisible {
visibility: hidden;
}
.text-hide {
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
.hidden {
display: none !important;
visibility: hidden !important;
}
.affix {
position: fixed;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}

View File

@@ -1,63 +0,0 @@
/* ========================================================================
* DOM-based Routing
* Based on http://goo.gl/EUTi53 by Paul Irish
*
* Only fires on body classes that match. If a body class contains a dash,
* replace the dash with an underscore when adding it to the object below.
*
* .noConflict()
* The routing is enclosed within an anonymous function so that you can
* always reference jQuery with $, even when in .noConflict() mode.
*
* Google CDN, Latest jQuery
* To use the default WordPress version of jQuery, go to lib/config.php and
* remove or comment out: add_theme_support('jquery-cdn');
* ======================================================================== */
(function($) {
// Use this variable to set up the common and page specific functions. If you
// rename this variable, you will also need to rename the namespace below.
var Roots = {
// All pages
common: {
init: function() {
// JavaScript to be fired on all pages
}
},
// Home page
home: {
init: function() {
// JavaScript to be fired on the home page
}
},
// About us page, note the change from about-us to about_us.
about_us: {
init: function() {
// JavaScript to be fired on the about us page
}
}
};
// The routing fires all common scripts, followed by the page specific scripts.
// Add additional events for more control over timing e.g. a finalize event
var UTIL = {
fire: function(func, funcname, args) {
var namespace = Roots;
funcname = (funcname === undefined) ? 'init' : funcname;
if (func !== '' && namespace[func] && typeof namespace[func][funcname] === 'function') {
namespace[func][funcname](args);
}
},
loadEvents: function() {
UTIL.fire('common');
$.each(document.body.className.replace(/-/g, '_').split(/\s+/),function(i,classnm) {
UTIL.fire(classnm);
});
}
};
$(document).ready(UTIL.loadEvents);
})(jQuery); // Fully reference jQuery after this point.

View File

@@ -1,92 +0,0 @@
//
// Bootstrap
//
// Comment out any unused components
// --------------------------------------------------
// Variables
@import "../vendor/bootstrap/less/variables";
// Mixins: Utilities
@import "../vendor/bootstrap/less/mixins/hide-text";
@import "../vendor/bootstrap/less/mixins/opacity";
@import "../vendor/bootstrap/less/mixins/image";
@import "../vendor/bootstrap/less/mixins/labels";
@import "../vendor/bootstrap/less/mixins/reset-filter";
@import "../vendor/bootstrap/less/mixins/resize";
@import "../vendor/bootstrap/less/mixins/responsive-visibility";
@import "../vendor/bootstrap/less/mixins/size";
@import "../vendor/bootstrap/less/mixins/tab-focus";
@import "../vendor/bootstrap/less/mixins/text-emphasis";
@import "../vendor/bootstrap/less/mixins/text-overflow";
@import "../vendor/bootstrap/less/mixins/vendor-prefixes";
// Mixins: Components
@import "../vendor/bootstrap/less/mixins/alerts";
@import "../vendor/bootstrap/less/mixins/buttons";
@import "../vendor/bootstrap/less/mixins/panels";
@import "../vendor/bootstrap/less/mixins/pagination";
@import "../vendor/bootstrap/less/mixins/list-group";
@import "../vendor/bootstrap/less/mixins/nav-divider";
@import "../vendor/bootstrap/less/mixins/forms";
@import "../vendor/bootstrap/less/mixins/progress-bar";
@import "../vendor/bootstrap/less/mixins/table-row";
// Mixins: Skins
@import "../vendor/bootstrap/less/mixins/background-variant";
@import "../vendor/bootstrap/less/mixins/border-radius";
@import "../vendor/bootstrap/less/mixins/gradients";
// Mixins: Layout
@import "../vendor/bootstrap/less/mixins/clearfix";
@import "../vendor/bootstrap/less/mixins/center-block";
@import "../vendor/bootstrap/less/mixins/nav-vertical-align";
@import "../vendor/bootstrap/less/mixins/grid-framework";
@import "../vendor/bootstrap/less/mixins/grid";
// Reset
@import "../vendor/bootstrap/less/normalize";
@import "../vendor/bootstrap/less/print";
@import "../vendor/bootstrap/less/glyphicons";
// Core CSS
@import "../vendor/bootstrap/less/scaffolding";
@import "../vendor/bootstrap/less/type";
@import "../vendor/bootstrap/less/code";
@import "../vendor/bootstrap/less/grid";
@import "../vendor/bootstrap/less/tables";
@import "../vendor/bootstrap/less/forms";
@import "../vendor/bootstrap/less/buttons";
// Components
@import "../vendor/bootstrap/less/component-animations";
@import "../vendor/bootstrap/less/dropdowns";
@import "../vendor/bootstrap/less/button-groups";
@import "../vendor/bootstrap/less/input-groups";
@import "../vendor/bootstrap/less/navs";
@import "../vendor/bootstrap/less/navbar";
@import "../vendor/bootstrap/less/breadcrumbs";
@import "../vendor/bootstrap/less/pagination";
@import "../vendor/bootstrap/less/pager";
@import "../vendor/bootstrap/less/labels";
@import "../vendor/bootstrap/less/badges";
@import "../vendor/bootstrap/less/jumbotron";
@import "../vendor/bootstrap/less/thumbnails";
@import "../vendor/bootstrap/less/alerts";
@import "../vendor/bootstrap/less/progress-bars";
@import "../vendor/bootstrap/less/media";
@import "../vendor/bootstrap/less/list-group";
@import "../vendor/bootstrap/less/panels";
@import "../vendor/bootstrap/less/responsive-embed";
@import "../vendor/bootstrap/less/wells";
@import "../vendor/bootstrap/less/close";
// Components w/ JavaScript
@import "../vendor/bootstrap/less/modals";
@import "../vendor/bootstrap/less/tooltip";
@import "../vendor/bootstrap/less/popovers";
@import "../vendor/bootstrap/less/carousel";
// Utility classes
@import "../vendor/bootstrap/less/utilities";
@import "../vendor/bootstrap/less/responsive-utilities";

View File

@@ -1,17 +0,0 @@
// Grid settings
// -------------------------
@main-sm-columns: @grid-columns;
@sidebar-sm-columns: 4;
// Brand colors
// -------------------------
@brand-primary: #27ae60;
// Glyphicons path
// -------------------------
@icon-font-path: "../vendor/bootstrap/fonts/";

View File

@@ -1,13 +0,0 @@
// Captions
.wp-caption {
&:extend(.thumbnail all);
}
.wp-caption-text {
&:extend(.thumbnail .caption all);
}
// Gallery shortcode
.gallery-row {
padding: (@line-height-computed / 2) 0;
}

View File

@@ -1 +0,0 @@
.content-info { }

View File

@@ -1 +0,0 @@
.banner { }

View File

@@ -1,5 +0,0 @@
.hentry header { }
.hentry time { }
.hentry .byline { }
.hentry .entry-content { }
.hentry footer { }

View File

@@ -1,3 +0,0 @@
.sidebar {
.make-sm-column(@sidebar-sm-columns);
}

View File

@@ -1,20 +0,0 @@
// Bootstrap
@import "_bootstrap";
// Variable overrides and custom variables
@import "_variables";
// Roots
@import "_global"; // Base styling & custom mixins
@import "components/_buttons"; // Button tweaks
@import "components/_comments"; // Comment styling
@import "components/_forms"; // Form tweaks
@import "components/_media"; // WordPress media
@import "components/_wp-classes"; // WordPress generated classes
@import "layouts/_general"; // General styling
@import "layouts/_header"; // Header styling
@import "layouts/_sidebar"; // Sidebar styling
@import "layouts/_footer"; // Footer styling
@import "layouts/_pages"; // Page styling
@import "layouts/pages/_home"; // Home page styling
@import "layouts/_posts"; // Post styling

30
assets/manifest.json Normal file
View File

@@ -0,0 +1,30 @@
{
"dependencies": {
"main.js": {
"files": [
"scripts/main.js"
],
"main": true
},
"main.css": {
"files": [
"styles/main.less"
],
"main": true
},
"editor-style.css": {
"files": [
"styles/editor-style.less"
]
},
"jquery.js": {
"bower": ["jquery"]
},
"modernizr.js": {
"bower": ["modernizr"]
}
},
"config": {
"devUrl": "example.dev"
}
}

81
assets/scripts/main.js Normal file
View File

@@ -0,0 +1,81 @@
/* ========================================================================
* DOM-based Routing
* Based on http://goo.gl/EUTi53 by Paul Irish
*
* Only fires on body classes that match. If a body class contains a dash,
* replace the dash with an underscore when adding it to the object below.
*
* .noConflict()
* The routing is enclosed within an anonymous function so that you can
* always reference jQuery with $, even when in .noConflict() mode.
*
* Google CDN, Latest jQuery
* To use the default WordPress version of jQuery, go to lib/config.php and
* remove or comment out: add_theme_support('jquery-cdn');
* ======================================================================== */
(function($) {
// Use this variable to set up the common and page specific functions. If you
// rename this variable, you will also need to rename the namespace below.
var Sage = {
// All pages
'common': {
init: function() {
// JavaScript to be fired on all pages
},
finalize: function() {
// JavaScript to be fired on all pages, after page specific JS is fired
}
},
// Home page
'home': {
init: function() {
// JavaScript to be fired on the home page
},
finalize: function() {
// JavaScript to be fired on the home page, after the init JS
}
},
// About us page, note the change from about-us to about_us.
'about_us': {
init: function() {
// JavaScript to be fired on the about us page
}
}
};
// The routing fires all common scripts, followed by the page specific scripts.
// Add additional events for more control over timing e.g. a finalize event
var UTIL = {
fire: function(func, funcname, args) {
var fire;
var namespace = Sage;
funcname = (funcname === undefined) ? 'init' : funcname;
fire = func !== '';
fire = fire && namespace[func];
fire = fire && typeof namespace[func][funcname] === 'function';
if (fire) {
namespace[func][funcname](args);
}
},
loadEvents: function() {
// Fire common init JS
UTIL.fire('common');
// Fire page-specific init JS, and then finalize JS
$.each(document.body.className.replace(/-/g, '_').split(/\s+/), function(i, classnm) {
UTIL.fire(classnm);
UTIL.fire(classnm, 'finalize');
});
// Fire common finalize JS
UTIL.fire('common', 'finalize');
}
};
// Load Events
$(document).ready(UTIL.loadEvents);
})(jQuery); // Fully reference jQuery after this point.

View File

@@ -0,0 +1,6 @@
// Grid settings
@main-sm-columns: @grid-columns;
@sidebar-sm-columns: 4;
// Colors
@brand-primary: #27ae60;

View File

@@ -1,10 +1,10 @@
// Content wrapper
.wrap { }
// Main content area
// Grid system
.main {
.make-sm-column(@main-sm-columns);
.sidebar-primary & {
.make-sm-column(@main-sm-columns - @sidebar-sm-columns);
}
}
.sidebar {
.make-sm-column(@sidebar-sm-columns);
}

View File

@@ -1,6 +1,12 @@
// WordPress Generated Classes
// http://codex.wordpress.org/CSS#WordPress_Generated_Classes
// Media alignment
.alignnone {
margin-left: 0;
margin-right: 0;
max-width: 100%;
}
.aligncenter {
display: block;
margin: (@line-height-computed / 2) auto;
@@ -9,14 +15,8 @@
.alignright {
margin-bottom: (@line-height-computed / 2);
}
figure.alignnone {
margin-left: 0;
margin-right: 0;
max-width: 100%;
}
@media (min-width: @screen-sm-min) {
// Only float images if not on an extra small device like smartphones
// Only float if not on an extra small device
.alignleft {
float: left;
margin-right: (@line-height-computed / 2);
@@ -26,3 +26,17 @@ figure.alignnone {
margin-left: (@line-height-computed / 2);
}
}
// Captions
.wp-caption {
&:extend(.thumbnail all);
}
.wp-caption-text {
&:extend(.thumbnail .caption all);
}
// Text meant only for screen readers
.screen-reader-text {
&:extend(.sr-only all);
&:extend(.sr-only-focusable all);
}

View File

@@ -0,0 +1,5 @@
@import "main";
body {
margin: 12px !important;
}

View File

View File

17
assets/styles/main.less Normal file
View File

@@ -0,0 +1,17 @@
// Automatically injected Bower dependencies via wiredep (never manually edit this block)
// bower:less
@import "../../bower_components/bootstrap/less/bootstrap.less";
// endbower
@import "common/_variables";
@import "common/_global";
@import "components/_buttons";
@import "components/_comments";
@import "components/_forms";
@import "components/_grid";
@import "components/_wp-classes";
@import "layouts/_header";
@import "layouts/_sidebar";
@import "layouts/_footer";
@import "layouts/_pages";
@import "layouts/_posts";

View File

@@ -0,0 +1,12 @@
// How to get started using Sass instead of Less:
//
// 1. Run `bower install bootstrap-sass-official --save`
// 2. Rename this file to `main.scss` and remove `main.less`
// 3. Rename `editor-style.less` to `editor-style.scss`
// 4. Update the `assets/manifest.json` styles dependenies from `.less` to `.scss`
//
// Feel free to remove this file if you're using Less
// bower:sass
@import "../../bower_components/bootstrap-sass-official/assets/stylesheets/_bootstrap.scss";
// endbower

View File

@@ -1,33 +1,38 @@
<?php
namespace Roots\Sage;
use Roots\Sage\Config;
use Roots\Sage\Wrapper;
?>
<?php get_template_part('templates/head'); ?>
<body <?php body_class(); ?>>
<!--[if lt IE 8]>
<div class="alert alert-warning">
<?php _e('You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.', 'roots'); ?>
</div>
<![endif]-->
<?php
do_action('get_header');
get_template_part('templates/header');
?>
<div class="wrap container" role="document">
<div class="content row">
<main class="main" role="main">
<?php include roots_template_path(); ?>
</main><!-- /.main -->
<?php if (roots_display_sidebar()) : ?>
<aside class="sidebar" role="complementary">
<?php include roots_sidebar_path(); ?>
</aside><!-- /.sidebar -->
<?php endif; ?>
</div><!-- /.content -->
</div><!-- /.wrap -->
<?php get_template_part('templates/footer'); ?>
<?php wp_footer(); ?>
</body>
<body <?php body_class(); ?>>
<!--[if lt IE 9]>
<div class="alert alert-warning">
<?php _e('You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.', 'sage'); ?>
</div>
<![endif]-->
<?php
do_action('get_header');
get_template_part('templates/header');
?>
<div class="wrap container" role="document">
<div class="content row">
<main class="main" role="main">
<?php include Wrapper\template_path(); ?>
</main><!-- /.main -->
<?php if (Config\display_sidebar()) : ?>
<aside class="sidebar" role="complementary">
<?php include Wrapper\sidebar_path(); ?>
</aside><!-- /.sidebar -->
<?php endif; ?>
</div><!-- /.content -->
</div><!-- /.wrap -->
<?php
get_template_part('templates/footer');
wp_footer();
?>
</body>
</html>

View File

@@ -1,21 +1,63 @@
{
"name": "roots",
"version": "7.0.3",
"homepage": "http://roots.io",
"name": "sage",
"homepage": "https://roots.io/sage/",
"authors": [
"Ben Word <ben@benword.com>"
],
"license": "MIT",
"private": true,
"ignore": [
"**/.*",
"node_modules",
"assets/vendor"
],
"dependencies": {
"modernizr": "2.8.2",
"jquery": "1.11.1",
"bootstrap": "3.3.1",
"respond": "1.4.2"
"jquery": "1.11.2",
"bootstrap": "3.3.2"
},
"overrides": {
"modernizr": {
"main": "./modernizr.js"
},
"bootstrap": {
"main": [
"./less/bootstrap.less",
"./js/transition.js",
"./js/alert.js",
"./js/button.js",
"./js/carousel.js",
"./js/collapse.js",
"./js/dropdown.js",
"./js/modal.js",
"./js/tooltip.js",
"./js/popover.js",
"./js/scrollspy.js",
"./js/tab.js",
"./js/affix.js",
"./fonts/glyphicons-halflings-regular.eot",
"./fonts/glyphicons-halflings-regular.svg",
"./fonts/glyphicons-halflings-regular.ttf",
"./fonts/glyphicons-halflings-regular.woff",
"./fonts/glyphicons-halflings-regular.woff2"
]
},
"bootstrap-sass-official": {
"main": [
"./assets/stylesheets/_bootstrap.scss",
"./assets/javascripts/bootstrap/transition.js",
"./assets/javascripts/bootstrap/alert.js",
"./assets/javascripts/bootstrap/button.js",
"./assets/javascripts/bootstrap/carousel.js",
"./assets/javascripts/bootstrap/collapse.js",
"./assets/javascripts/bootstrap/dropdown.js",
"./assets/javascripts/bootstrap/modal.js",
"./assets/javascripts/bootstrap/tooltip.js",
"./assets/javascripts/bootstrap/popover.js",
"./assets/javascripts/bootstrap/scrollspy.js",
"./assets/javascripts/bootstrap/tab.js",
"./assets/javascripts/bootstrap/affix.js",
"./assets/fonts/bootstrap/glyphicons-halflings-regular.eot",
"./assets/fonts/bootstrap/glyphicons-halflings-regular.svg",
"./assets/fonts/bootstrap/glyphicons-halflings-regular.ttf",
"./assets/fonts/bootstrap/glyphicons-halflings-regular.woff",
"./assets/fonts/bootstrap/glyphicons-halflings-regular.woff2"
]
}
}
}

View File

@@ -1,31 +1,30 @@
<?php
/**
* Roots includes
* Sage includes
*
* The $roots_includes array determines the code library included in your theme.
* 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/roots/pull/1042
* @link https://github.com/roots/sage/pull/1042
*/
$roots_includes = array(
'lib/utils.php', // Utility functions
'lib/init.php', // Initial theme setup and constants
'lib/wrapper.php', // Theme wrapper class
'lib/sidebar.php', // Sidebar class
'lib/config.php', // Configuration
'lib/activation.php', // Theme activation
'lib/titles.php', // Page titles
'lib/nav.php', // Custom nav modifications
'lib/gallery.php', // Custom [gallery] modifications
'lib/scripts.php', // Scripts and stylesheets
'lib/extras.php', // Custom functions
);
$sage_includes = [
'lib/utils.php', // Utility functions
'lib/init.php', // Initial theme setup and constants
'lib/wrapper.php', // Theme wrapper class
'lib/conditional-tag-check.php', // ConditionalTagCheck class
'lib/config.php', // Configuration
'lib/assets.php', // Scripts and stylesheets
'lib/titles.php', // Page titles
'lib/nav.php', // Custom nav modifications
'lib/gallery.php', // Custom [gallery] modifications
'lib/extras.php', // Custom functions
];
foreach ($roots_includes as $file) {
foreach ($sage_includes as $file) {
if (!$filepath = locate_template($file)) {
trigger_error(sprintf(__('Error locating %s for inclusion', 'roots'), $file), E_USER_ERROR);
trigger_error(sprintf(__('Error locating %s for inclusion', 'sage'), $file), E_USER_ERROR);
}
require_once $filepath;

258
gulpfile.js Normal file
View File

@@ -0,0 +1,258 @@
// ## Globals
/*global $:true*/
var $ = require('gulp-load-plugins')();
var argv = require('yargs').argv;
var browserSync = require('browser-sync');
var gulp = require('gulp');
var lazypipe = require('lazypipe');
var merge = require('merge-stream');
// See https://github.com/austinpray/asset-builder
var manifest = require('asset-builder')('./assets/manifest.json');
// `path` - Paths to base asset directories. With trailing slashes.
// - `path.source` - Path to the source files. Default: `assets/`
// - `path.dist` - Path to the build directory. Default: `dist/`
var path = manifest.paths;
// `config` - Store arbitrary configuration values here.
var config = manifest.config || {};
// `globs` - These ultimately end up in their respective `gulp.src`.
// - `globs.js` - Array of asset-builder JS dependency objects. Example:
// ```
// {type: 'js', name: 'main.js', globs: []}
// ```
// - `globs.css` - Array of asset-builder CSS dependency objects. Example:
// ```
// {type: 'css', name: 'main.css', globs: []}
// ```
// - `globs.fonts` - Array of font path globs.
// - `globs.images` - Array of image path globs.
// - `globs.bower` - Array of all the main Bower files.
var globs = manifest.globs;
// `project` - paths to first-party assets.
// - `project.js` - Array of first-party JS assets.
// - `project.css` - Array of first-party CSS assets.
var project = manifest.getProjectGlobs();
// CLI options
var enabled = {
// Enable static asset revisioning when `--production`
rev: argv.production,
// Disable source maps when `--production`
maps: !argv.production,
// Fail styles task on error when `--production`
failStyleTask: argv.production
};
// Path to the compiled assets manifest in the dist directory
var revManifest = path.dist + 'assets.json';
// ## Reusable Pipelines
// See https://github.com/OverZealous/lazypipe
// ### CSS processing pipeline
// Example
// ```
// gulp.src(cssFiles)
// .pipe(cssTasks('main.css')
// .pipe(gulp.dest(path.dist + 'styles'))
// ```
var cssTasks = function(filename) {
return lazypipe()
.pipe(function() {
return $.if(!enabled.failStyleTask, $.plumber());
})
.pipe(function() {
return $.if(enabled.maps, $.sourcemaps.init());
})
.pipe(function() {
return $.if('*.less', $.less());
})
.pipe(function() {
return $.if('*.scss', $.sass({
outputStyle: 'nested', // libsass doesn't support expanded yet
precision: 10,
includePaths: ['.'],
errLogToConsole: !enabled.failStyleTask
}));
})
.pipe($.concat, filename)
.pipe($.pleeease, {
autoprefixer: {
browsers: [
'last 2 versions', 'ie 8', 'ie 9', 'android 2.3', 'android 4',
'opera 12'
]
}
})
.pipe(function() {
return $.if(enabled.rev, $.rev());
})
.pipe(function() {
return $.if(enabled.maps, $.sourcemaps.write('.'));
})();
};
// ### JS processing pipeline
// Example
// ```
// gulp.src(jsFiles)
// .pipe(jsTasks('main.js')
// .pipe(gulp.dest(path.dist + 'scripts'))
// ```
var jsTasks = function(filename) {
return lazypipe()
.pipe(function() {
return $.if(enabled.maps, $.sourcemaps.init());
})
.pipe($.concat, filename)
.pipe($.uglify)
.pipe(function() {
return $.if(enabled.rev, $.rev());
})
.pipe(function() {
return $.if(enabled.maps, $.sourcemaps.write('.'));
})();
};
// ### Write to rev manifest
// If there are any revved files then write them to the rev manifest.
// See https://github.com/sindresorhus/gulp-rev
var writeToManifest = function(directory) {
return lazypipe()
.pipe(gulp.dest, path.dist + directory)
.pipe(function() {
return $.if('**/*.{js,css}', browserSync.reload({stream:true}));
})
.pipe($.rev.manifest, revManifest, {
base: path.dist,
merge: true
})
.pipe(gulp.dest, path.dist)();
};
// ## Gulp tasks
// Run `gulp -T` for a task summary
// ### Styles
// `gulp styles` - Compiles, combines, and optimizes Bower CSS and project CSS.
// By default this task will only log a warning if a precompiler error is
// raised. If the `--production` flag is set: this task will fail outright.
gulp.task('styles', ['wiredep'], function() {
var merged = merge();
manifest.forEachDependency('css', function(dep) {
var cssTasksInstance = cssTasks(dep.name);
if (!enabled.failStyleTask) {
cssTasksInstance.on('error', function(err) {
console.error(err.message);
this.emit('end');
});
}
merged.add(gulp.src(dep.globs, {base: 'styles'})
.pipe(cssTasksInstance));
});
return merged
.pipe(writeToManifest('styles'));
});
// ### Scripts
// `gulp scripts` - Runs JSHint then compiles, combines, and optimizes Bower JS
// and project JS.
gulp.task('scripts', ['jshint'], function() {
var merged = merge();
manifest.forEachDependency('js', function(dep) {
merged.add(
gulp.src(dep.globs, {base: 'scripts'})
.pipe(jsTasks(dep.name))
);
});
return merged
.pipe(writeToManifest('scripts'));
});
// ### Fonts
// `gulp fonts` - Grabs all the fonts and outputs them in a flattened directory
// structure. See: https://github.com/armed/gulp-flatten
gulp.task('fonts', function() {
return gulp.src(globs.fonts)
.pipe($.flatten())
.pipe(gulp.dest(path.dist + 'fonts'));
});
// ### Images
// `gulp images` - Run lossless compression on all the images.
gulp.task('images', function() {
return gulp.src(globs.images)
.pipe($.imagemin({
progressive: true,
interlaced: true,
svgoPlugins: [{removeUnknownsAndDefaults: false}]
}))
.pipe(gulp.dest(path.dist + 'images'));
});
// ### JSHint
// `gulp jshint` - Lints configuration JSON and project JS.
gulp.task('jshint', function() {
return gulp.src([
'bower.json', 'gulpfile.js'
].concat(project.js))
.pipe($.jshint())
.pipe($.jshint.reporter('jshint-stylish'))
.pipe($.jshint.reporter('fail'));
});
// ### Clean
// `gulp clean` - Deletes the build folder entirely.
gulp.task('clean', require('del').bind(null, [path.dist]));
// ### Watch
// `gulp watch` - Use BrowserSync to proxy your dev server and synchronize code
// changes across devices. Specify the hostname of your dev server at
// `manifest.config.devUrl`. When a modification is made to an asset, run the
// build step for that asset and inject the changes into the page.
// See: http://www.browsersync.io
gulp.task('watch', function() {
browserSync({
proxy: config.devUrl,
snippetOptions: {
whitelist: ['/wp-admin/admin-ajax.php'],
blacklist: ['/wp-admin/**']
}
});
gulp.watch([path.source + 'styles/**/*'], ['styles']);
gulp.watch([path.source + 'scripts/**/*'], ['jshint', 'scripts']);
gulp.watch([path.source + 'fonts/**/*'], ['fonts']);
gulp.watch([path.source + 'images/**/*'], ['images']);
gulp.watch(['bower.json'], ['wiredep']);
gulp.watch('**/*.php', function() {
browserSync.reload();
});
});
// ### Build
// `gulp build` - Run all the build tasks but don't clean up beforehand.
// Generally you should be running `gulp` instead of `gulp build`.
gulp.task('build', ['styles', 'scripts', 'fonts', 'images']);
// ### Wiredep
// `gulp wiredep` - Automatically inject Less and Sass Bower dependencies. See
// https://github.com/taptapship/wiredep
gulp.task('wiredep', function() {
var wiredep = require('wiredep').stream;
return gulp.src(project.css)
.pipe(wiredep())
.pipe($.changed(path.source + 'styles', {
hasChanged: $.changed.compareSha1Digest
}))
.pipe(gulp.dest(path.source + 'styles'));
});
// ### Gulp
// `gulp` - Run a complete build. To compile for production run `gulp --production`.
gulp.task('default', ['clean'], function() {
gulp.start('build');
});

View File

@@ -2,20 +2,13 @@
<?php if (!have_posts()) : ?>
<div class="alert alert-warning">
<?php _e('Sorry, no results were found.', 'roots'); ?>
<?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_format()); ?>
<?php get_template_part('templates/content', get_post_type() != 'post' ? get_post_type() : get_post_format()); ?>
<?php endwhile; ?>
<?php if ($wp_query->max_num_pages > 1) : ?>
<nav class="post-nav">
<ul class="pager">
<li class="previous"><?php next_posts_link(__('&larr; Older posts', 'roots')); ?></li>
<li class="next"><?php previous_posts_link(__('Newer posts &rarr;', 'roots')); ?></li>
</ul>
</nav>
<?php endif; ?>
<?php the_posts_navigation(); ?>

View File

@@ -1,212 +0,0 @@
msgid ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: 404.php:4
msgid "Sorry, but the page you were trying to view does not exist."
msgstr ""
#: 404.php:7
msgid "It looks like this was the result of either:"
msgstr ""
#: 404.php:9
msgid "a mistyped address"
msgstr ""
#: 404.php:10
msgid "an out-of-date link"
msgstr ""
#: base.php:6
msgid ""
"You are using an <strong>outdated</strong> browser. Please <a href=\"http://"
"browsehappy.com/\">upgrade your browser</a> to improve your experience."
msgstr ""
#: functions.php:28
msgid "Error locating %s for inclusion"
msgstr ""
#: index.php:5
msgid "Sorry, no results were found."
msgstr ""
#: index.php:17
msgid "&larr; Older posts"
msgstr ""
#: index.php:18
msgid "Newer posts &rarr;"
msgstr ""
#: lib/activation.php:28 lib/activation.php:29
msgid "Theme Activation"
msgstr ""
#: lib/activation.php:50
msgid "%s Theme Activation"
msgstr ""
#: lib/activation.php:52
msgid ""
"These settings are optional and should usually be used only on a fresh "
"installation"
msgstr ""
#: lib/activation.php:59 lib/activation.php:62
msgid "Create static front page?"
msgstr ""
#: lib/activation.php:64 lib/activation.php:76 lib/activation.php:88
#: lib/activation.php:100
msgid "Yes"
msgstr ""
#: lib/activation.php:65 lib/activation.php:77 lib/activation.php:89
#: lib/activation.php:101
msgid "No"
msgstr ""
#: lib/activation.php:67
msgid "Create a page called Home and set it to be the static front page"
msgstr ""
#: lib/activation.php:71
msgid "Change permalink structure?"
msgstr ""
#: lib/activation.php:74
msgid "Update permalink structure?"
msgstr ""
#: lib/activation.php:79
msgid "Change permalink structure to /&#37;postname&#37;/"
msgstr ""
#: lib/activation.php:83 lib/activation.php:86
msgid "Create navigation menu?"
msgstr ""
#: lib/activation.php:91
msgid "Create the Primary Navigation menu and set the location"
msgstr ""
#: lib/activation.php:95 lib/activation.php:98
msgid "Add pages to menu?"
msgstr ""
#: lib/activation.php:103
msgid "Add all current published pages to the Primary Navigation"
msgstr ""
#: lib/activation.php:126 lib/activation.php:147
msgid "Home"
msgstr ""
#: lib/activation.php:173 lib/activation.php:176 lib/activation.php:190
#: lib/init.php:13
msgid "Primary Navigation"
msgstr ""
#: lib/extras.php:6
msgid "Continued"
msgstr ""
#: lib/init.php:40
msgid "Primary"
msgstr ""
#: lib/init.php:49
msgid "Footer"
msgstr ""
#: lib/titles.php:10
msgid "Latest Posts"
msgstr ""
#: lib/titles.php:19
msgid "Daily Archives: %s"
msgstr ""
#: lib/titles.php:21
msgid "Monthly Archives: %s"
msgstr ""
#: lib/titles.php:23
msgid "Yearly Archives: %s"
msgstr ""
#: lib/titles.php:26
msgid "Author Archives: %s"
msgstr ""
#: lib/titles.php:31
msgid "Search Results for %s"
msgstr ""
#: lib/titles.php:33
msgid "Not Found"
msgstr ""
#: templates/comments.php:9
msgctxt "comments title"
msgid "One response to &ldquo;%2$s&rdquo;"
msgid_plural "%1$s responses to &ldquo;%2$s&rdquo;"
msgstr[0] ""
msgstr[1] ""
#: templates/comments.php:19
msgid "&larr; Older comments"
msgstr ""
#: templates/comments.php:22
msgid "Newer comments &rarr;"
msgstr ""
#: templates/comments.php:31
msgid "Comments are closed."
msgstr ""
#: templates/content-single.php:11
msgid "Pages:"
msgstr ""
#: templates/entry-meta.php:2
msgid "By"
msgstr ""
#: templates/searchform.php:2
msgid "Search for:"
msgstr ""
#: templates/searchform.php:4 templates/searchform.php:6
msgid "Search"
msgstr ""
#. Theme Name of the plugin/theme
msgid "Roots Starter Theme"
msgstr ""
#. Theme URI of the plugin/theme
msgid "http://roots.io/starter-theme/"
msgstr ""
#. Description of the plugin/theme
msgid ""
"Roots is a WordPress starter theme based on HTML5 Boilerplate & Bootstrap. "
"<a href=\"https://github.com/roots/roots/contributors\">Contribute on "
"GitHub</a>"
msgstr ""
#. Author of the plugin/theme
msgid "Roots"
msgstr ""
#. Author URI of the plugin/theme
msgid "http://roots.io/"
msgstr ""
#. Template Name of the plugin/theme
msgid "Custom Template"
msgstr ""

111
lang/sage.pot Normal file
View File

@@ -0,0 +1,111 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: 404.php:4
msgid "Sorry, but the page you were trying to view does not exist."
msgstr ""
#: base.php:14
msgid ""
"You are using an <strong>outdated</strong> browser. Please <a href=\"http://"
"browsehappy.com/\">upgrade your browser</a> to improve your experience."
msgstr ""
#: functions.php:27
msgid "Error locating %s for inclusion"
msgstr ""
#: index.php:5
msgid "Sorry, no results were found."
msgstr ""
#: lib/extras.php:31
msgid "Continued"
msgstr ""
#: lib/init.php:22
msgid "Primary Navigation"
msgstr ""
#: lib/init.php:49
msgid "Primary"
msgstr ""
#: lib/init.php:58
msgid "Footer"
msgstr ""
#: lib/titles.php:13
msgid "Latest Posts"
msgstr ""
#: lib/titles.php:18
msgid "Search Results for %s"
msgstr ""
#: lib/titles.php:20
msgid "Not Found"
msgstr ""
#: templates/comments.php:9
msgctxt "comments title"
msgid "One response to &ldquo;%2$s&rdquo;"
msgid_plural "%1$s responses to &ldquo;%2$s&rdquo;"
msgstr[0] ""
msgstr[1] ""
#: templates/comments.php:19
msgid "&larr; Older comments"
msgstr ""
#: templates/comments.php:22
msgid "Newer comments &rarr;"
msgstr ""
#: templates/comments.php:31
msgid "Comments are closed."
msgstr ""
#: templates/content-page.php:2 templates/content-single.php:11
msgid "Pages:"
msgstr ""
#: templates/entry-meta.php:2
msgid "By"
msgstr ""
#: templates/searchform.php:2
msgid "Search for:"
msgstr ""
#: templates/searchform.php:4 templates/searchform.php:6
msgid "Search"
msgstr ""
#. Theme Name of the plugin/theme
msgid "Sage Starter Theme"
msgstr ""
#. Theme URI of the plugin/theme
msgid "https://roots.io/sage/"
msgstr ""
#. Description of the plugin/theme
msgid ""
"Sage is a WordPress starter theme. <a href=\"https://github.com/roots/sage"
"\">Contribute on GitHub</a>"
msgstr ""
#. Author of the plugin/theme
msgid "Roots"
msgstr ""
#. Author URI of the plugin/theme
msgid "https://roots.io/"
msgstr ""
#. Template Name of the plugin/theme
msgid "Custom Template"
msgstr ""

View File

@@ -1,215 +0,0 @@
<?php
/**
* Theme activation
*/
if (is_admin() && isset($_GET['activated']) && 'themes.php' == $GLOBALS['pagenow']) {
wp_redirect(admin_url('themes.php?page=theme_activation_options'));
exit;
}
function roots_theme_activation_options_init() {
register_setting(
'roots_activation_options',
'roots_theme_activation_options'
);
}
add_action('admin_init', 'roots_theme_activation_options_init');
function roots_activation_options_page_capability() {
return 'edit_theme_options';
}
add_filter('option_page_capability_roots_activation_options', 'roots_activation_options_page_capability');
function roots_theme_activation_options_add_page() {
$roots_activation_options = roots_get_theme_activation_options();
if (!$roots_activation_options) {
add_theme_page(
__('Theme Activation', 'roots'),
__('Theme Activation', 'roots'),
'edit_theme_options',
'theme_activation_options',
'roots_theme_activation_options_render_page'
);
} else {
if (is_admin() && isset($_GET['page']) && $_GET['page'] === 'theme_activation_options') {
flush_rewrite_rules();
wp_redirect(admin_url('themes.php'));
exit;
}
}
}
add_action('admin_menu', 'roots_theme_activation_options_add_page', 50);
function roots_get_theme_activation_options() {
return get_option('roots_theme_activation_options');
}
function roots_theme_activation_options_render_page() { ?>
<div class="wrap">
<h2><?php printf(__('%s Theme Activation', 'roots'), wp_get_theme()); ?></h2>
<div class="update-nag">
<?php _e('These settings are optional and should usually be used only on a fresh installation', 'roots'); ?>
</div>
<?php settings_errors(); ?>
<form method="post" action="options.php">
<?php settings_fields('roots_activation_options'); ?>
<table class="form-table">
<tr valign="top"><th scope="row"><?php _e('Create static front page?', 'roots'); ?></th>
<td>
<fieldset>
<legend class="screen-reader-text"><span><?php _e('Create static front page?', 'roots'); ?></span></legend>
<select name="roots_theme_activation_options[create_front_page]" id="create_front_page">
<option selected="selected" value="true"><?php echo _e('Yes', 'roots'); ?></option>
<option value="false"><?php echo _e('No', 'roots'); ?></option>
</select>
<p class="description"><?php printf(__('Create a page called Home and set it to be the static front page', 'roots')); ?></p>
</fieldset>
</td>
</tr>
<tr valign="top"><th scope="row"><?php _e('Change permalink structure?', 'roots'); ?></th>
<td>
<fieldset>
<legend class="screen-reader-text"><span><?php _e('Update permalink structure?', 'roots'); ?></span></legend>
<select name="roots_theme_activation_options[change_permalink_structure]" id="change_permalink_structure">
<option selected="selected" value="true"><?php echo _e('Yes', 'roots'); ?></option>
<option value="false"><?php echo _e('No', 'roots'); ?></option>
</select>
<p class="description"><?php printf(__('Change permalink structure to /&#37;postname&#37;/', 'roots')); ?></p>
</fieldset>
</td>
</tr>
<tr valign="top"><th scope="row"><?php _e('Create navigation menu?', 'roots'); ?></th>
<td>
<fieldset>
<legend class="screen-reader-text"><span><?php _e('Create navigation menu?', 'roots'); ?></span></legend>
<select name="roots_theme_activation_options[create_navigation_menus]" id="create_navigation_menus">
<option selected="selected" value="true"><?php echo _e('Yes', 'roots'); ?></option>
<option value="false"><?php echo _e('No', 'roots'); ?></option>
</select>
<p class="description"><?php printf(__('Create the Primary Navigation menu and set the location', 'roots')); ?></p>
</fieldset>
</td>
</tr>
<tr valign="top"><th scope="row"><?php _e('Add pages to menu?', 'roots'); ?></th>
<td>
<fieldset>
<legend class="screen-reader-text"><span><?php _e('Add pages to menu?', 'roots'); ?></span></legend>
<select name="roots_theme_activation_options[add_pages_to_primary_navigation]" id="add_pages_to_primary_navigation">
<option selected="selected" value="true"><?php echo _e('Yes', 'roots'); ?></option>
<option value="false"><?php echo _e('No', 'roots'); ?></option>
</select>
<p class="description"><?php printf(__('Add all current published pages to the Primary Navigation', 'roots')); ?></p>
</fieldset>
</td>
</tr>
</table>
<?php submit_button(); ?>
</form>
</div>
<?php }
function roots_theme_activation_action() {
if (!($roots_theme_activation_options = roots_get_theme_activation_options())) {
return;
}
if (strpos(wp_get_referer(), 'page=theme_activation_options') === false) {
return;
}
if ($roots_theme_activation_options['create_front_page'] === 'true') {
$roots_theme_activation_options['create_front_page'] = false;
$default_pages = array(__('Home', 'roots'));
$existing_pages = get_pages();
$temp = array();
foreach ($existing_pages as $page) {
$temp[] = $page->post_title;
}
$pages_to_create = array_diff($default_pages, $temp);
foreach ($pages_to_create as $new_page_title) {
$add_default_pages = array(
'post_title' => $new_page_title,
'post_content' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat, orci ac laoreet cursus, dolor sem luctus lorem, eget consequat magna felis a magna. Aliquam scelerisque condimentum ante, eget facilisis tortor lobortis in. In interdum venenatis justo eget consequat. Morbi commodo rhoncus mi nec pharetra. Aliquam erat volutpat. Mauris non lorem eu dolor hendrerit dapibus. Mauris mollis nisl quis sapien posuere consectetur. Nullam in sapien at nisi ornare bibendum at ut lectus. Pellentesque ut magna mauris. Nam viverra suscipit ligula, sed accumsan enim placerat nec. Cras vitae metus vel dolor ultrices sagittis. Duis venenatis augue sed risus laoreet congue ac ac leo. Donec fermentum accumsan libero sit amet iaculis. Duis tristique dictum enim, ac fringilla risus bibendum in. Nunc ornare, quam sit amet ultricies gravida, tortor mi malesuada urna, quis commodo dui nibh in lacus. Nunc vel tortor mi. Pellentesque vel urna a arcu adipiscing imperdiet vitae sit amet neque. Integer eu lectus et nunc dictum sagittis. Curabitur commodo vulputate fringilla. Sed eleifend, arcu convallis adipiscing congue, dui turpis commodo magna, et vehicula sapien turpis sit amet nisi.',
'post_status' => 'publish',
'post_type' => 'page'
);
wp_insert_post($add_default_pages);
}
$home = get_page_by_title(__('Home', 'roots'));
update_option('show_on_front', 'page');
update_option('page_on_front', $home->ID);
$home_menu_order = array(
'ID' => $home->ID,
'menu_order' => -1
);
wp_update_post($home_menu_order);
}
if ($roots_theme_activation_options['change_permalink_structure'] === 'true') {
$roots_theme_activation_options['change_permalink_structure'] = false;
if (get_option('permalink_structure') !== '/%postname%/') {
global $wp_rewrite;
$wp_rewrite->set_permalink_structure('/%postname%/');
flush_rewrite_rules();
}
}
if ($roots_theme_activation_options['create_navigation_menus'] === 'true') {
$roots_theme_activation_options['create_navigation_menus'] = false;
$roots_nav_theme_mod = false;
$primary_nav = wp_get_nav_menu_object(__('Primary Navigation', 'roots'));
if (!$primary_nav) {
$primary_nav_id = wp_create_nav_menu(__('Primary Navigation', 'roots'), array('slug' => 'primary_navigation'));
$roots_nav_theme_mod['primary_navigation'] = $primary_nav_id;
} else {
$roots_nav_theme_mod['primary_navigation'] = $primary_nav->term_id;
}
if ($roots_nav_theme_mod) {
set_theme_mod('nav_menu_locations', $roots_nav_theme_mod);
}
}
if ($roots_theme_activation_options['add_pages_to_primary_navigation'] === 'true') {
$roots_theme_activation_options['add_pages_to_primary_navigation'] = false;
$primary_nav = wp_get_nav_menu_object(__('Primary Navigation', 'roots'));
$primary_nav_term_id = (int) $primary_nav->term_id;
$menu_items= wp_get_nav_menu_items($primary_nav_term_id);
if (!$menu_items || empty($menu_items)) {
$pages = get_pages();
foreach($pages as $page) {
$item = array(
'menu-item-object-id' => $page->ID,
'menu-item-object' => 'page',
'menu-item-type' => 'post_type',
'menu-item-status' => 'publish'
);
wp_update_nav_menu_item($primary_nav_term_id, 0, $item);
}
}
}
update_option('roots_theme_activation_options', $roots_theme_activation_options);
}
add_action('admin_init','roots_theme_activation_action');
function roots_deactivation() {
delete_option('roots_theme_activation_options');
}
add_action('switch_theme', 'roots_deactivation');

174
lib/assets.php Normal file
View File

@@ -0,0 +1,174 @@
<?php
namespace Roots\Sage\Assets;
/**
* Scripts and stylesheets
*
* Enqueue stylesheets in the following order:
* 1. /theme/dist/styles/main.css
*
* Enqueue scripts in the following order:
* 1. Latest jQuery via Google CDN (if enabled in config.php)
* 2. /theme/dist/scripts/modernizr.js
* 3. /theme/dist/scripts/main.js
*
* Google Analytics is loaded after enqueued scripts if:
* - An ID has been defined in config.php
* - You're not logged in as an administrator
*/
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 (WP_ENV !== 'development' && array_key_exists($file, $manifest->get())) {
return $dist_path . $directory . $manifest->get()[$file];
} else {
return $dist_path . $directory . $file;
}
}
function bower_map_to_cdn($dependency, $fallback) {
static $bower;
if (empty($bower)) {
$bower_path = get_template_directory() . '/bower.json';
$bower = new JsonManifest($bower_path);
}
$templates = [
'google' => '//ajax.googleapis.com/ajax/libs/%name%/%version%/%file%'
];
$version = $bower->getPath('dependencies.' . $dependency['name']);
if (isset($version) && preg_match('/^(\d+\.){2}\d+$/', $version)) {
$search = ['%name%', '%version%', '%file%'];
$replace = [$dependency['name'], $version, $dependency['file']];
return str_replace($search, $replace, $templates[$dependency['cdn']]);
} else {
return $fallback;
}
}
function assets() {
wp_enqueue_style('sage_css', asset_path('styles/main.css'), false, null);
/**
* Grab Google CDN's latest jQuery with a protocol relative URL; fallback to local if offline
* jQuery & Modernizr load in the footer per HTML5 Boilerplate's recommendation: http://goo.gl/nMGR7P
* If a plugin enqueues jQuery-dependent scripts in the head, jQuery will load in the head to meet the plugin's dependencies
* To explicitly load jQuery in the head, change the last wp_enqueue_script parameter to false
*/
if (!is_admin() && current_theme_supports('jquery-cdn')) {
wp_deregister_script('jquery');
wp_register_script('jquery', bower_map_to_cdn([
'name' => 'jquery',
'cdn' => 'google',
'file' => 'jquery.min.js'
], asset_path('scripts/jquery.js')), [], null, true);
add_filter('script_loader_src', __NAMESPACE__ . '\\jquery_local_fallback', 10, 2);
}
if (is_single() && comments_open() && get_option('thread_comments')) {
wp_enqueue_script('comment-reply');
}
wp_enqueue_script('modernizr', asset_path('scripts/modernizr.js'), [], null, true);
wp_enqueue_script('jquery');
wp_enqueue_script('sage_js', asset_path('scripts/main.js'), [], null, true);
}
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\\assets', 100);
// http://wordpress.stackexchange.com/a/12450
function jquery_local_fallback($src, $handle = null) {
static $add_jquery_fallback = false;
if ($add_jquery_fallback) {
echo '<script>window.jQuery || document.write(\'<script src="' . get_template_directory_uri() . '/dist/scripts/jquery.js"><\/script>\')</script>' . "\n";
$add_jquery_fallback = false;
}
if ($handle === 'jquery') {
$add_jquery_fallback = true;
}
return $src;
}
add_action('wp_head', __NAMESPACE__ . '\\jquery_local_fallback');
/**
* Google Analytics snippet from HTML5 Boilerplate
*
* Cookie domain is 'auto' configured. See: http://goo.gl/VUCHKM
*/
function google_analytics() {
?>
<script>
<?php if (WP_ENV === 'production' && !current_user_can('manage_options')) : ?>
(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
e=o.createElement(i);r=o.getElementsByTagName(i)[0];
e.src='//www.google-analytics.com/analytics.js';
r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
<?php else : ?>
function ga() {
if (window.console) {
console.log('Google Analytics: ' + [].slice.call(arguments));
}
}
<?php endif; ?>
ga('create','<?= GOOGLE_ANALYTICS_ID; ?>','auto');ga('send','pageview');
</script>
<?php
}
if (GOOGLE_ANALYTICS_ID) {
add_action('wp_footer', __NAMESPACE__ . '\\google_analytics', 20);
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Roots\Sage;
/**
* Utility class which takes an array of conditional tags (or any function which returns a boolean)
* and returns `true` if *any* of them are `true`, and `false` otherwise.
*
* @param array list of conditional tags (http://codex.wordpress.org/Conditional_Tags)
* or custom function which returns a boolean
*
* @return boolean
*/
class ConditionalTagCheck {
private $conditionals;
public $result = true;
public function __construct($conditionals = []) {
$this->conditionals = $conditionals;
$conditionals = array_map([$this, 'checkConditionalTag'], $this->conditionals);
if (in_array(true, $conditionals)) {
$this->result = false;
}
}
private function checkConditionalTag($conditional_tag) {
$conditional_arg = is_array($conditional_tag) ? $conditional_tag[1] : false;
$conditional_tag = $conditional_arg ? $conditional_tag[0] : $conditional_tag;
if (function_exists($conditional_tag)) {
return $conditional_arg ? $conditional_tag($conditional_arg) : $conditional_tag();
} else {
return false;
}
}
}

View File

@@ -1,67 +1,68 @@
<?php
namespace Roots\Sage\Config;
use Roots\Sage;
/**
* Enable theme features
*/
add_theme_support('soil-clean-up'); // Enable clean up from Soil
add_theme_support('soil-relative-urls'); // Enable relative URLs from Soil
add_theme_support('soil-nice-search'); // Enable /?s= to /search/ redirect from Soil
add_theme_support('soil-nice-search'); // Enable nice search from Soil
add_theme_support('bootstrap-gallery'); // Enable Bootstrap's thumbnails component on [gallery]
add_theme_support('jquery-cdn'); // Enable to load jQuery from the Google CDN
/**
* Configuration values
*/
define('GOOGLE_ANALYTICS_ID', ''); // UA-XXXXX-Y (Note: Universal Analytics only, not Classic Analytics)
if (!defined('GOOGLE_ANALYTICS_ID')) {
// Format: UA-XXXXX-Y (Note: Universal Analytics only)
define('GOOGLE_ANALYTICS_ID', '');
}
if (!defined('WP_ENV')) {
define('WP_ENV', 'production'); // scripts.php checks for values 'production' or 'development'
// Fallback if WP_ENV isn't defined in your WordPress config
// Used in lib/assets.php to check for 'development' or 'production'
define('WP_ENV', 'production');
}
/**
* Add body class if sidebar is active
*/
function roots_sidebar_body_class($classes) {
if (roots_display_sidebar()) {
$classes[] = 'sidebar-primary';
}
return $classes;
}
add_filter('body_class', 'roots_sidebar_body_class');
/**
* Define which pages shouldn't have the sidebar
*
* See lib/sidebar.php for more details
*/
function roots_display_sidebar() {
function display_sidebar() {
static $display;
if (!isset($display)) {
$sidebar_config = new Roots_Sidebar(
$conditionalCheck = new Sage\ConditionalTagCheck(
/**
* Conditional tag checks (http://codex.wordpress.org/Conditional_Tags)
* Any of these conditional tags that return true won't show the sidebar
* Any of these conditional tags that return true won't show the sidebar.
* You can also specify your own custom function as long as it returns a boolean.
*
* To use a function that accepts arguments, use the following format:
*
* array('function_name', array('arg1', 'arg2'))
* ['function_name', ['arg1', 'arg2']]
*
* Note: The second element must be an array even if there's only 1 argument.
*
* Examples:
*
* 'is_single'
* 'is_archive'
* ['is_page', ['about-me']]
* ['is_tax', ['flavor', 'mild']]
* ['is_page_template', ['about.php']]
* ['is_post_type_archive', [['foo', 'bar', 'baz']]]
*
* The second element must be an array even if there's only 1 argument.
*/
array(
[
'is_404',
'is_front_page'
),
/**
* Page template checks (via is_page_template())
* Any of these page templates that return true won't show the sidebar
*/
array(
'template-custom.php'
)
]
);
$display = apply_filters('roots/display_sidebar', $sidebar_config->display);
}
$display = apply_filters('sage/display_sidebar', $conditionalCheck->result);
}
return $display;
}
@@ -73,4 +74,6 @@ function roots_display_sidebar() {
* Example: If the content area is 640px wide, set $content_width = 620; so images and videos will not overflow.
* Default: 1140px is the default Bootstrap container width.
*/
if (!isset($content_width)) { $content_width = 1140; }
if (!isset($content_width)) {
$content_width = 1140;
}

View File

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

View File

@@ -1,4 +1,7 @@
<?php
namespace Roots\Sage\Gallery;
/**
* Clean up gallery_shortcode()
*
@@ -7,7 +10,7 @@
*
* @link http://getbootstrap.com/components/#thumbnails
*/
function roots_gallery($attr) {
function gallery($attr) {
$post = get_post();
static $instance = 0;
@@ -33,7 +36,7 @@ function roots_gallery($attr) {
}
}
extract(shortcode_atts(array(
extract(shortcode_atts([
'order' => 'ASC',
'orderby' => 'menu_order ID',
'id' => $post->ID,
@@ -45,7 +48,7 @@ function roots_gallery($attr) {
'include' => '',
'exclude' => '',
'link' => ''
), $attr));
], $attr));
$id = intval($id);
$columns = (12 % $columns == 0) ? $columns: 4;
@@ -56,16 +59,16 @@ function roots_gallery($attr) {
}
if (!empty($include)) {
$_attachments = get_posts(array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby));
$_attachments = get_posts(['include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby]);
$attachments = array();
$attachments = [];
foreach ($_attachments as $key => $val) {
$attachments[$val->ID] = $_attachments[$key];
}
} elseif (!empty($exclude)) {
$attachments = get_children(array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby));
$attachments = get_children(['post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby]);
} else {
$attachments = get_children(array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby));
$attachments = get_children(['post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby]);
}
if (empty($attachments)) {
@@ -90,7 +93,7 @@ function roots_gallery($attr) {
$image = wp_get_attachment_link($id, $size, false, false);
break;
case 'none':
$image = wp_get_attachment_image($id, $size, false, array('class' => 'thumbnail img-thumbnail'));
$image = wp_get_attachment_image($id, $size, false, ['class' => 'thumbnail img-thumbnail']);
break;
default:
$image = wp_get_attachment_link($id, $size, true, false);
@@ -115,15 +118,15 @@ function roots_gallery($attr) {
}
if (current_theme_supports('bootstrap-gallery')) {
remove_shortcode('gallery');
add_shortcode('gallery', 'roots_gallery');
add_shortcode('gallery', __NAMESPACE__ . '\\gallery');
add_filter('use_default_gallery_style', '__return_null');
}
/**
* Add class="thumbnail img-thumbnail" to attachment items
*/
function roots_attachment_link_class($html) {
function attachment_link_class($html) {
$html = str_replace('<a', '<a class="thumbnail img-thumbnail"', $html);
return $html;
}
add_filter('wp_get_attachment_link', 'roots_attachment_link_class', 10, 1);
add_filter('wp_get_attachment_link', __NAMESPACE__ . '\\attachment_link_class', 10, 1);

View File

@@ -1,11 +1,16 @@
<?php
namespace Roots\Sage\Init;
use Roots\Sage\Assets;
/**
* Roots initial setup and constants
* Theme setup
*/
function roots_setup() {
function setup() {
// Make theme available for translation
// Community translations can be found at https://github.com/roots/roots-translations
load_theme_textdomain('roots', get_template_directory() . '/lang');
// 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
@@ -13,9 +18,9 @@ function roots_setup() {
// Register wp_nav_menu() menus
// http://codex.wordpress.org/Function_Reference/register_nav_menus
register_nav_menus(array(
'primary_navigation' => __('Primary Navigation', 'roots')
));
register_nav_menus([
'primary_navigation' => __('Primary Navigation', 'sage')
]);
// Add post thumbnails
// http://codex.wordpress.org/Post_Thumbnails
@@ -25,37 +30,37 @@ function roots_setup() {
// Add post formats
// http://codex.wordpress.org/Post_Formats
add_theme_support('post-formats', array('aside', 'gallery', 'link', 'image', 'quote', 'video', 'audio'));
add_theme_support('post-formats', ['aside', 'gallery', 'link', 'image', 'quote', 'video', 'audio']);
// Add HTML5 markup for captions
// http://codex.wordpress.org/Function_Reference/add_theme_support#HTML5
add_theme_support('html5', array('caption', 'comment-form', 'comment-list'));
add_theme_support('html5', ['caption', 'comment-form', 'comment-list']);
// Tell the TinyMCE editor to use a custom stylesheet
add_editor_style('/assets/css/editor-style.css');
add_editor_style(Assets\asset_path('styles/editor-style.css'));
}
add_action('after_setup_theme', 'roots_setup');
add_action('after_setup_theme', __NAMESPACE__ . '\\setup');
/**
* Register sidebars
*/
function roots_widgets_init() {
register_sidebar(array(
'name' => __('Primary', 'roots'),
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>',
));
'after_title' => '</h3>'
]);
register_sidebar(array(
'name' => __('Footer', 'roots'),
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>',
));
'after_title' => '</h3>'
]);
}
add_action('widgets_init', 'roots_widgets_init');
add_action('widgets_init', __NAMESPACE__ . '\\widgets_init');

View File

@@ -1,4 +1,9 @@
<?php
namespace Roots\Sage\Nav;
use Roots\Sage\Utils;
/**
* Cleaner walker for wp_nav_menu()
*
@@ -6,35 +11,45 @@
* <li id="menu-item-8" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-8"><a href="/">Home</a></li>
* <li id="menu-item-9" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-9"><a href="/sample-page/">Sample Page</a></l
*
* Roots_Nav_Walker example output:
* SageNavWalker example output:
* <li class="menu-home"><a href="/">Home</a></li>
* <li class="menu-sample-page"><a href="/sample-page/">Sample Page</a></li>
*/
class Roots_Nav_Walker extends Walker_Nav_Menu {
function check_current($classes) {
class SageNavWalker extends \Walker_Nav_Menu {
private $cpt; // Boolean, is current post a custom post type
private $archive; // Stores the archive page for current URL
public function __construct() {
add_filter('nav_menu_css_class', array($this, 'cssClasses'), 10, 2);
add_filter('nav_menu_item_id', '__return_null');
$cpt = get_post_type();
$this->cpt = in_array($cpt, get_post_types(array('_builtin' => false)));
$this->archive = get_post_type_archive_link($cpt);
}
public function checkCurrent($classes) {
return preg_match('/(current[-_])|active|dropdown/', $classes);
}
function start_lvl(&$output, $depth = 0, $args = array()) {
// @codingStandardsIgnoreStart
function start_lvl(&$output, $depth = 0, $args = []) {
$output .= "\n<ul class=\"dropdown-menu\">\n";
}
function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
function start_el(&$output, $item, $depth = 0, $args = [], $id = 0) {
$item_html = '';
parent::start_el($item_html, $item, $depth, $args);
if ($item->is_dropdown && ($depth === 0)) {
$item_html = str_replace('<a', '<a class="dropdown-toggle" data-toggle="dropdown" data-target="#"', $item_html);
$item_html = str_replace('</a>', ' <b class="caret"></b></a>', $item_html);
}
elseif (stristr($item_html, 'li class="divider')) {
} elseif (stristr($item_html, 'li class="divider')) {
$item_html = preg_replace('/<a[^>]*>.*?<\/a>/iU', '', $item_html);
}
elseif (stristr($item_html, 'li class="dropdown-header')) {
} elseif (stristr($item_html, 'li class="dropdown-header')) {
$item_html = preg_replace('/<a[^>]*>(.*)<\/a>/iU', '$1', $item_html);
}
$item_html = apply_filters('roots/wp_nav_menu_item', $item_html);
$item_html = apply_filters('sage/wp_nav_menu_item', $item_html);
$output .= $item_html;
}
@@ -43,49 +58,65 @@ class Roots_Nav_Walker extends Walker_Nav_Menu {
if ($element->is_dropdown) {
$element->classes[] = 'dropdown';
foreach ($children_elements[$element->ID] as $child) {
if ($child->current_item_parent || Utils\url_compare($this->archive, $child->url)) {
$element->classes[] = 'active';
}
}
}
$element->is_active = strpos($this->archive, $element->url);
if ($element->is_active) {
$element->classes[] = 'active';
}
parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output);
}
// @codingStandardsIgnoreEnd
public function cssClasses($classes, $item) {
$slug = sanitize_title($item->title);
if ($this->cpt) {
$classes = str_replace('current_page_parent', '', $classes);
if (Utils\url_compare($this->archive, $item->url)) {
$classes[] = 'active';
}
}
$classes = preg_replace('/(current(-menu-|[-_]page[-_])(item|parent|ancestor))/', 'active', $classes);
$classes = preg_replace('/^((menu|page)[-_\w+]+)+/', '', $classes);
$classes[] = 'menu-' . $slug;
$classes = array_unique($classes);
return array_filter($classes, 'Roots\\Sage\\Utils\\is_element_empty');
}
}
/**
* Remove the id="" on nav menu items
* Return 'menu-slug' for nav menu classes
*/
function roots_nav_menu_css_class($classes, $item) {
$slug = sanitize_title($item->title);
$classes = preg_replace('/(current(-menu-|[-_]page[-_])(item|parent|ancestor))/', 'active', $classes);
$classes = preg_replace('/^((menu|page)[-_\w+]+)+/', '', $classes);
$classes[] = 'menu-' . $slug;
$classes = array_unique($classes);
return array_filter($classes, 'is_element_empty');
}
add_filter('nav_menu_css_class', 'roots_nav_menu_css_class', 10, 2);
add_filter('nav_menu_item_id', '__return_null');
/**
* Clean up wp_nav_menu_args
*
* Remove the container
* Use Roots_Nav_Walker() by default
* Remove the id="" on nav menu items
*/
function roots_nav_menu_args($args = '') {
$roots_nav_menu_args = array();
$roots_nav_menu_args['container'] = false;
function nav_menu_args($args = '') {
$nav_menu_args = [];
$nav_menu_args['container'] = false;
if (!$args['items_wrap']) {
$roots_nav_menu_args['items_wrap'] = '<ul class="%2$s">%3$s</ul>';
$nav_menu_args['items_wrap'] = '<ul class="%2$s">%3$s</ul>';
}
if (!$args['depth']) {
$roots_nav_menu_args['depth'] = 2;
$nav_menu_args['depth'] = 2;
}
return array_merge($args, $roots_nav_menu_args);
return array_merge($args, $nav_menu_args);
}
add_filter('wp_nav_menu_args', 'roots_nav_menu_args');
add_filter('wp_nav_menu_args', __NAMESPACE__ . '\\nav_menu_args');
add_filter('nav_menu_item_id', '__return_null');

View File

@@ -1,104 +0,0 @@
<?php
/**
* Scripts and stylesheets
*
* Enqueue stylesheets in the following order:
* 1. /theme/assets/css/main.css
*
* Enqueue scripts in the following order:
* 1. jquery-1.11.1.min.js via Google CDN
* 2. /theme/assets/js/vendor/modernizr.min.js
* 3. /theme/assets/js/scripts.js
*
* Google Analytics is loaded after enqueued scripts if:
* - An ID has been defined in config.php
* - You're not logged in as an administrator
*/
function roots_scripts() {
/**
* The build task in Grunt renames production assets with a hash
* Read the asset names from assets-manifest.json
*/
if (WP_ENV === 'development') {
$assets = array(
'css' => '/assets/css/main.css',
'js' => '/assets/js/scripts.js',
'modernizr' => '/assets/vendor/modernizr/modernizr.js',
'jquery' => '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.js'
);
} else {
$get_assets = file_get_contents(get_template_directory() . '/assets/manifest.json');
$assets = json_decode($get_assets, true);
$assets = array(
'css' => '/assets/css/main.min.css?' . $assets['assets/css/main.min.css']['hash'],
'js' => '/assets/js/scripts.min.js?' . $assets['assets/js/scripts.min.js']['hash'],
'modernizr' => '/assets/js/vendor/modernizr.min.js',
'jquery' => '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'
);
}
wp_enqueue_style('roots_css', get_template_directory_uri() . $assets['css'], false, null);
/**
* jQuery is loaded using the same method from HTML5 Boilerplate:
* Grab Google CDN's latest jQuery with a protocol relative URL; fallback to local if offline
* It's kept in the header instead of footer to avoid conflicts with plugins.
*/
if (!is_admin() && current_theme_supports('jquery-cdn')) {
wp_deregister_script('jquery');
wp_register_script('jquery', $assets['jquery'], array(), null, true);
add_filter('script_loader_src', 'roots_jquery_local_fallback', 10, 2);
}
if (is_single() && comments_open() && get_option('thread_comments')) {
wp_enqueue_script('comment-reply');
}
wp_enqueue_script('modernizr', get_template_directory_uri() . $assets['modernizr'], array(), null, true);
wp_enqueue_script('jquery');
wp_enqueue_script('roots_js', get_template_directory_uri() . $assets['js'], array(), null, true);
}
add_action('wp_enqueue_scripts', 'roots_scripts', 100);
// http://wordpress.stackexchange.com/a/12450
function roots_jquery_local_fallback($src, $handle = null) {
static $add_jquery_fallback = false;
if ($add_jquery_fallback) {
echo '<script>window.jQuery || document.write(\'<script src="' . get_template_directory_uri() . '/assets/vendor/jquery/dist/jquery.min.js?1.11.1"><\/script>\')</script>' . "\n";
$add_jquery_fallback = false;
}
if ($handle === 'jquery') {
$add_jquery_fallback = true;
}
return $src;
}
add_action('wp_head', 'roots_jquery_local_fallback');
/**
* Google Analytics snippet from HTML5 Boilerplate
*
* Cookie domain is 'auto' configured. See: http://goo.gl/VUCHKM
*/
function roots_google_analytics() { ?>
<script>
<?php if (WP_ENV === 'production') : ?>
(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
e=o.createElement(i);r=o.getElementsByTagName(i)[0];
e.src='//www.google-analytics.com/analytics.js';
r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
<?php else : ?>
function ga() {
console.log('GoogleAnalytics: ' + [].slice.call(arguments));
}
<?php endif; ?>
ga('create','<?php echo GOOGLE_ANALYTICS_ID; ?>','auto');ga('send','pageview');
</script>
<?php }
if (GOOGLE_ANALYTICS_ID && (WP_ENV !== 'production' || !current_user_can('manage_options'))) {
add_action('wp_footer', 'roots_google_analytics', 20);
}

View File

@@ -1,46 +0,0 @@
<?php
/**
* Determines whether or not to display the sidebar based on an array of conditional tags or page templates.
*
* If any of the is_* conditional tags or is_page_template(template_file) checks return true, the sidebar will NOT be displayed.
*
* @link http://roots.io/the-roots-sidebar/
*
* @param array list of conditional tags (http://codex.wordpress.org/Conditional_Tags)
* @param array list of page templates. These will be checked via is_page_template()
*
* @return boolean True will display the sidebar, False will not
*/
class Roots_Sidebar {
private $conditionals;
private $templates;
public $display = true;
function __construct($conditionals = array(), $templates = array()) {
$this->conditionals = $conditionals;
$this->templates = $templates;
$conditionals = array_map(array($this, 'check_conditional_tag'), $this->conditionals);
$templates = array_map(array($this, 'check_page_template'), $this->templates);
if (in_array(true, $conditionals) || in_array(true, $templates)) {
$this->display = false;
}
}
private function check_conditional_tag($conditional_tag) {
$conditional_arg = is_array($conditional_tag) ? $conditional_tag[1] : false;
$conditional_tag = $conditional_arg ? $conditional_tag[0] : $conditional_tag;
if (function_exists($conditional_tag)) {
return $conditional_arg ? $conditional_tag($conditional_arg) : $conditional_tag();
} else {
return false;
}
}
private function check_page_template($page_template) {
return is_page_template($page_template) || Roots_Wrapping::$base . '.php' === $page_template;
}
}

View File

@@ -1,20 +1,23 @@
<?php
namespace Roots\Sage\Titles;
/**
* Page titles
*/
function roots_title() {
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', 'roots');
return __('Latest Posts', 'sage');
}
} elseif (is_archive()) {
return get_the_archive_title();
} elseif (is_search()) {
return sprintf(__('Search Results for %s', 'roots'), get_search_query());
return sprintf(__('Search Results for %s', 'sage'), get_search_query());
} elseif (is_404()) {
return __('Not Found', 'roots');
return __('Not Found', 'sage');
} else {
return get_the_title();
}

View File

@@ -1,30 +1,48 @@
<?php
namespace Roots\Sage\Utils;
/**
* Utility functions
* Tell WordPress to use searchform.php from the templates/ directory
*/
function get_search_form() {
$form = '';
locate_template('/templates/searchform.php', true, false);
return $form;
}
add_filter('get_search_form', __NAMESPACE__ . '\\get_search_form');
/**
* Make a URL relative
*/
function root_relative_url($input) {
preg_match('|https?://([^/]+)(/.*)|i', $input, $matches);
if (!isset($matches[1]) || !isset($matches[2])) {
return $input;
} elseif (($matches[1] === $_SERVER['SERVER_NAME']) || $matches[1] === $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT']) {
return wp_make_link_relative($input);
} else {
return $input;
}
}
/**
* Compare URL against relative URL
*/
function url_compare($url, $rel) {
$url = trailingslashit($url);
$rel = trailingslashit($rel);
if ((strcasecmp($url, $rel) === 0) || root_relative_url($url) == $rel) {
return true;
} else {
return false;
}
}
/**
* Check if element is empty
*/
function is_element_empty($element) {
$element = trim($element);
return !empty($element);
}
// Tell WordPress to use searchform.php from the templates/ directory
function roots_get_search_form() {
$form = '';
locate_template('/templates/searchform.php', true, false);
return $form;
}
add_filter('get_search_form', 'roots_get_search_form');
/**
* Add page slug to body_class() classes if it doesn't exist
*/
function roots_body_class($classes) {
// Add post/page slug
if (is_single() || is_page() && !is_front_page()) {
if (!in_array(basename(get_permalink()), $classes)) {
$classes[] = basename(get_permalink());
}
}
return $classes;
}
add_filter('body_class', 'roots_body_class');

View File

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

View File

@@ -1,14 +1,15 @@
{
"name": "roots",
"version": "7.0.3",
"name": "sage",
"version": "8.0.0",
"author": "Ben Word <ben@benword.com>",
"homepage": "http://roots.io",
"homepage": "https://roots.io/sage/",
"private": true,
"repository": {
"type": "git",
"url": "git://github.com/roots/roots.git"
"url": "git://github.com/roots/sage.git"
},
"bugs": {
"url": "https://github.com/roots/roots/issues"
"url": "https://github.com/roots/sage/issues"
},
"licenses": [
{
@@ -17,23 +18,40 @@
}
],
"scripts": {
"postinstall": "node node_modules/bower/bin/bower install && grunt dev"
"build": "bower install && gulp",
"jshint": "gulp jshint",
"jscs": "jscs gulpfile.js assets/scripts/*.js"
},
"engines": {
"node": ">= 0.10.0"
"node": ">= 0.10.0",
"npm": ">=2.1.5"
},
"devDependencies": {
"bower": ">=1.3.12",
"grunt": "~0.4.5",
"grunt-autoprefixer": "~1.0.1",
"grunt-contrib-concat": "~0.5.0",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-less": "~0.12.0",
"grunt-contrib-uglify": "~0.6.0",
"grunt-contrib-watch": "~0.6.1",
"grunt-modernizr": "~0.6.0",
"grunt-wp-assets": "~0.2.6",
"load-grunt-tasks": "~1.0.0",
"time-grunt": "~1.0.0"
"asset-builder": "^0.4.1",
"browser-sync": "^2.0.1",
"del": "^1.1.1",
"gulp": "^3.8.10",
"gulp-changed": "^1.1.0",
"gulp-concat": "^2.3.4",
"gulp-flatten": "0.0.4",
"gulp-if": "^1.2.5",
"gulp-imagemin": "^2.0.0",
"gulp-jshint": "^1.8.4",
"gulp-less": "^3.0.1",
"gulp-load-plugins": "^0.8.0",
"gulp-pleeease": "^1.1.0",
"gulp-plumber": "^0.6.3",
"gulp-rename": "^1.2.0",
"gulp-rev": "^3.0.0",
"gulp-sass": "^1.2.4",
"gulp-sourcemaps": "^1.1.1",
"gulp-uglify": "^1.0.1",
"imagemin-pngcrush": "^4.0.0",
"jshint-stylish": "^1.0.0",
"lazypipe": "^0.2.2",
"merge-stream": "^0.1.7",
"traverse": "^0.6.6",
"wiredep": "^2.1.0",
"yargs": "^3.2.1"
}
}

45
ruleset.xml Normal file
View File

@@ -0,0 +1,45 @@
<?xml version="1.0"?>
<ruleset name="Roots">
<description>Roots Coding Standards</description>
<!-- Use PSR-2 as a base -->
<rule ref="PSR2">
<!-- Allow opening and closing braces for functions and classes to be on the same line -->
<exclude name="Squiz.Functions.MultiLineFunctionDeclaration.BraceOnSameLine"/>
<exclude name="PSR2.Classes.ClassDeclaration.OpenBraceNewLine"/>
<exclude name="Squiz.WhiteSpace.ScopeClosingBrace"/>
<!-- Disable newline after opening brace -->
<exclude name="Squiz.ControlStructures.ControlSignature.NewlineAfterOpenBrace"/>
<!-- Allow multiple PHP statements in the same line (usually in template files) -->
<exclude name="Generic.Formatting.DisallowMultipleStatements.SameLine"/>
<!-- Disable PSR-2 indentation rules that are buggy with 2 spaces -->
<exclude name="PSR2.ControlStructures.SwitchDeclaration.BreakIndent"/>
<exclude name="PSR2.Methods.FunctionCallSignature.Indent"/>
</rule>
<!-- Don't require a blank line after the last `use` in templates/ directory -->
<rule ref="PSR2.Namespaces.UseDeclaration.SpaceAfterLastUse">
<exclude-pattern>templates/*</exclude-pattern>
</rule>
<!-- Allow PHP closing tags on templates -->
<rule ref="Zend.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 -->
<rule ref="Generic.WhiteSpace.ScopeIndent">
<properties>
<property name="indent" value="2"/>
<property name="tabIndent" value="false"/>
</properties>
</rule>
</ruleset>

View File

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

View File

@@ -1,10 +1,10 @@
/*
Theme Name: Roots Starter Theme
Theme URI: http://roots.io/starter-theme/
Description: Roots is a WordPress starter theme based on HTML5 Boilerplate & Bootstrap. <a href="https://github.com/roots/roots/contributors">Contribute on GitHub</a>
Version: 7.0.3
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.0.0
Author: Roots
Author URI: http://roots.io/
Author URI: https://roots.io/
License: MIT License
License URI: http://opensource.org/licenses/MIT

View File

@@ -1,7 +1,7 @@
<?php
/*
Template Name: Custom Template
*/
/**
* Template Name: Custom Template
*/
?>
<?php while (have_posts()) : the_post(); ?>

View File

@@ -1,25 +1,25 @@
<?php
if (post_password_required()) {
return;
}
if (post_password_required()) {
return;
}
?>
<section id="comments" class="comments">
<?php if (have_comments()) : ?>
<h2><?php printf(_nx('One response to &ldquo;%2$s&rdquo;', '%1$s responses to &ldquo;%2$s&rdquo;', get_comments_number(), 'comments title', 'roots'), number_format_i18n(get_comments_number()), '<span>' . get_the_title() . '</span>'); ?></h2>
<h2><?php printf(_nx('One response to &ldquo;%2$s&rdquo;', '%1$s responses to &ldquo;%2$s&rdquo;', get_comments_number(), 'comments title', 'sage'), number_format_i18n(get_comments_number()), '<span>' . get_the_title() . '</span>'); ?></h2>
<ol class="comment-list">
<?php wp_list_comments(array('style' => 'ol', 'short_ping' => true)); ?>
<?php wp_list_comments(['style' => 'ol', 'short_ping' => true]); ?>
</ol>
<?php if (get_comment_pages_count() > 1 && get_option('page_comments')) : ?>
<nav>
<ul class="pager">
<?php if (get_previous_comments_link()) : ?>
<li class="previous"><?php previous_comments_link(__('&larr; Older comments', 'roots')); ?></li>
<li class="previous"><?php previous_comments_link(__('&larr; Older comments', 'sage')); ?></li>
<?php endif; ?>
<?php if (get_next_comments_link()) : ?>
<li class="next"><?php next_comments_link(__('Newer comments &rarr;', 'roots')); ?></li>
<li class="next"><?php next_comments_link(__('Newer comments &rarr;', 'sage')); ?></li>
<?php endif; ?>
</ul>
</nav>
@@ -28,7 +28,7 @@
<?php if (!comments_open() && get_comments_number() != '0' && post_type_supports(get_post_type(), 'comments')) : ?>
<div class="alert alert-warning">
<?php _e('Comments are closed.', 'roots'); ?>
<?php _e('Comments are closed.', 'sage'); ?>
</div>
<?php endif; ?>

View File

@@ -1,2 +1,2 @@
<?php the_content(); ?>
<?php wp_link_pages(array('before' => '<nav class="pagination">', 'after' => '</nav>')); ?>
<?php wp_link_pages(['before' => '<nav class="page-nav"><p>' . __('Pages:', 'sage'), 'after' => '</p></nav>']); ?>

View File

@@ -8,7 +8,7 @@
<?php the_content(); ?>
</div>
<footer>
<?php wp_link_pages(array('before' => '<nav class="page-nav"><p>' . __('Pages:', 'roots'), 'after' => '</p></nav>')); ?>
<?php wp_link_pages(['before' => '<nav class="page-nav"><p>' . __('Pages:', 'sage'), 'after' => '</p></nav>']); ?>
</footer>
<?php comments_template('/templates/comments.php'); ?>
</article>

View File

@@ -1,2 +1,2 @@
<time class="updated" datetime="<?php echo get_the_time('c'); ?>"><?php echo get_the_date(); ?></time>
<p class="byline author vcard"><?php echo __('By', 'roots'); ?> <a href="<?php echo get_author_posts_url(get_the_author_meta('ID')); ?>" rel="author" class="fn"><?php echo get_the_author(); ?></a></p>
<time class="updated" datetime="<?= get_the_time('c'); ?>"><?= get_the_date(); ?></time>
<p class="byline author vcard"><?= __('By', 'sage'); ?> <a href="<?= get_author_posts_url(get_the_author_meta('ID')); ?>" rel="author" class="fn"><?= get_the_author(); ?></a></p>

View File

@@ -1,11 +1,9 @@
<!doctype html>
<html class="no-js" <?php language_attributes(); ?>>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="alternate" type="application/rss+xml" title="<?php echo get_bloginfo('name'); ?> Feed" href="<?php echo esc_url(get_feed_link()); ?>">
<?php wp_head(); ?>
</head>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="alternate" type="application/rss+xml" title="<?= get_bloginfo('name'); ?> Feed" href="<?= esc_url(get_feed_link()); ?>">
<?php wp_head(); ?>
</head>

View File

@@ -1,3 +1,5 @@
<?php use Roots\Sage\Nav; ?>
<header class="banner navbar navbar-default navbar-static-top" role="banner">
<div class="container">
<div class="navbar-header">
@@ -7,14 +9,14 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="<?php echo esc_url(home_url('/')); ?>"><?php bloginfo('name'); ?></a>
<a class="navbar-brand" href="<?= esc_url(home_url('/')); ?>"><?php bloginfo('name'); ?></a>
</div>
<nav class="collapse navbar-collapse" role="navigation">
<?php
if (has_nav_menu('primary_navigation')) :
wp_nav_menu(array('theme_location' => 'primary_navigation', 'walker' => new Roots_Nav_Walker(), 'menu_class' => 'nav navbar-nav'));
endif;
if (has_nav_menu('primary_navigation')) :
wp_nav_menu(['theme_location' => 'primary_navigation', 'walker' => new Nav\SageNavWalker(), 'menu_class' => 'nav navbar-nav']);
endif;
?>
</nav>
</div>

View File

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

View File

@@ -1,9 +1,9 @@
<form role="search" method="get" class="search-form form-inline" action="<?php echo esc_url(home_url('/')); ?>">
<label class="sr-only"><?php _e('Search for:', 'roots'); ?></label>
<form role="search" method="get" class="search-form form-inline" action="<?= esc_url(home_url('/')); ?>">
<label class="sr-only"><?php _e('Search for:', 'sage'); ?></label>
<div class="input-group">
<input type="search" value="<?php echo get_search_query(); ?>" name="s" class="search-field form-control" placeholder="<?php _e('Search', 'roots'); ?> <?php bloginfo('name'); ?>" required>
<input type="search" value="<?= get_search_query(); ?>" name="s" class="search-field form-control" placeholder="<?php _e('Search', 'sage'); ?> <?php bloginfo('name'); ?>" required>
<span class="input-group-btn">
<button type="submit" class="search-submit btn btn-default"><?php _e('Search', 'roots'); ?></button>
<button type="submit" class="search-submit btn btn-default"><?php _e('Search', 'sage'); ?></button>
</span>
</div>
</form>