first commit

This commit is contained in:
Kevin Tessier 2020-05-20 15:48:29 +02:00
commit cf7a95d818
66 changed files with 3552 additions and 0 deletions

26
.env.example Normal file
View File

@ -0,0 +1,26 @@
DB_NAME='database_name'
DB_USER='database_user'
DB_PASSWORD='database_password'
# Optionally, you can use a data source name (DSN)
# When using a DSN, you can remove the DB_NAME, DB_USER, DB_PASSWORD, and DB_HOST variables
# DATABASE_URL='mysql://database_user:database_password@database_host:database_port/database_name'
# Optional variables
# DB_HOST='localhost'
# DB_PREFIX='wp_'
WP_ENV='development'
WP_HOME='http://example.com'
WP_SITEURL="${WP_HOME}/wp"
WP_DEBUG_LOG=/path/to/debug.log
# Generate your keys here: https://roots.io/salts.html
AUTH_KEY='generateme'
SECURE_AUTH_KEY='generateme'
LOGGED_IN_KEY='generateme'
NONCE_KEY='generateme'
AUTH_SALT='generateme'
SECURE_AUTH_SALT='generateme'
LOGGED_IN_SALT='generateme'
NONCE_SALT='generateme'

14
.github/workflows/issues.yml vendored Normal file
View File

@ -0,0 +1,14 @@
name: Issue closer
on: [issues]
jobs:
autoclose:
runs-on: ubuntu-latest
steps:
- name: Autoclose issues that did not follow issue template
uses: roots/issue-closer@v1.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
issue-close-message: "Hi @${issue.user.login},
It looks like the issue template is missing from this issue. Please take a look at the [Contribution Guidelines](https://github.com/roots/guidelines/blob/master/CONTRIBUTING.md), which will tell you **exactly** what your ticket has to contain in order to be processable.
Please **do not** use the issue tracker for personal support requests. Use [Roots Discourse](https://discourse.roots.io/) to ask the Roots community for help, or [hire someone from the community](https://discourse.roots.io/c/jobs)."
issue-pattern: ".*guidelines for Contributing.*"

25
.gitignore vendored Normal file
View File

@ -0,0 +1,25 @@
# Application
web/app/plugins/*
!web/app/plugins/.gitkeep
web/app/mu-plugins/*/
web/app/upgrade
web/app/uploads/*
!web/app/uploads/.gitkeep
# WordPress
web/wp
web/.htaccess
# Logs
*.log
# Dotenv
.env
.env.*
!.env.example
# Composer
/vendor
# WP-CLI
wp-cli.local.yml

383
CHANGELOG.md Normal file
View File

@ -0,0 +1,383 @@
### Head
### 1.13.4: 2020-04-24
* fix(mu-plugins): Bump bedrock-autoloader version ([#512](https://github.com/roots/bedrock/pull/512))
* fix(mu-plugins): A more sane fix for #510 ([#512](https://github.com/roots/bedrock/pull/512))
### 1.13.3: 2020-04-24
* enhance(ci): Add CircleCI workflow for PHP 7.4 ([#510](https://github.com/roots/bedrock/pull/511))
* fix(mu-plugins): Fix invalid array access notice on 7.4 ([#510](https://github.com/roots/bedrock/pull/510))
* enhance(composer): Add `only` option to wpackagist.org repository ([#508](https://github.com/roots/bedrock/pull/508))
### 1.13.2: 2020-04-01
* chore(deps): Bump WordPress to 5.4 ([#502](https://github.com/roots/bedrock/pull/502))
* chore(deps): Bump vlucas/phpdotenv ([#501](https://github.com/roots/bedrock/pull/502))
* enhance(config): Add `WP_DEBUG_LOG` ([#499](https://github.com/roots/bedrock/pull/499))
### 1.13.1: 2020-02-19
* fix(env): Makes .env.example compatible with breaking changes from vlucas/phpdotenv 4.x ([#493](https://github.com/roots/bedrock/pull/493))
### 1.13.0: 2020-02-17
* Update to WordPress 5.3.2 ([#489](https://github.com/roots/bedrock/pull/489))
* chore(deps): Bump vlucas/phpdotenv from 4.0.1 to 4.1.0 ([#487](https://github.com/roots/bedrock/pull/487))
* chore(deps): Bump vlucas/phpdotenv from 3.6.0 to 4.0.1 ([#485](https://github.com/roots/bedrock/pull/485))
* chore(deps): Bump composer/installers from 1.7.0 to 1.8.0 ([#492](https://github.com/roots/bedrock/pull/492))
* chore(deps-dev): Bump squizlabs/php_codesniffer from 3.4.2 to 3.5.4 ([#490](https://github.com/roots/bedrock/pull/490))
* Clean up docblocks & commenting ([#459](https://github.com/roots/bedrock/pull/459))
### 1.12.8: 2019-09-05
* Update to WordPress 5.2.3 ([#466](https://github.com/roots/bedrock/pull/466))
* Remove `phpcs.xml` from `.gitattributes` ([#464](https://github.com/roots/bedrock/pull/464))
* `ini_set()` fixes ([#463](https://github.com/roots/bedrock/pull/463))
* Editorconfig updates ([#457](https://github.com/roots/bedrock/pull/457))
* Bump `composer/installers` ([#462](https://github.com/roots/bedrock/pull/462))
* Better default composer options ([#456](https://github.com/roots/bedrock/pull/456))
* Ignore `.log` files ([#440](https://github.com/roots/bedrock/pull/440))
* Change to CircleCI ([82945d8](https://github.com/roots/bedrock/commit/82945d803d10cb072b7e786e0a81094ccb2d067b), [#460](https://github.com/roots/bedrock/pull/460))
### 1.12.7: 2019-06-19
* Update to WordPress 5.2.2 ([#444](https://github.com/roots/bedrock/pull/444))
* Bump `oscarotero/env` ([#443](https://github.com/roots/bedrock/pull/443))
* Bump `vlucas/phpdotenv` ([#442](https://github.com/roots/bedrock/pull/442))
* Bump `squizlabs/php_codesniffer` ([#441](https://github.com/roots/bedrock/pull/441))
* Remove unnecessary static variables ([#437](https://github.com/roots/bedrock/pull/437))
### 1.12.6: 2019-05-21
* Update to WordPress 5.2.1 ([#436](https://github.com/roots/bedrock/pull/436))
### 1.12.5: 2019-05-14
* Disable WordPress' built-in fatal error handler on development ([#432](https://github.com/roots/bedrock/pull/434))
### 1.12.4: 2019-05-07
* Update to WordPress 5.2 ([#432](https://github.com/roots/bedrock/pull/432))
* Configure WP-CLI `wp server` webroot ([#427](https://github.com/roots/bedrock/pull/427))
* Fix issue with `bedrock_autoloader` option ([#386](https://github.com/roots/bedrock/pull/386))
### 1.12.3: 2019-03-13
* Update to WordPress 5.1.1 ([#426](https://github.com/roots/bedrock/pull/426))
### 1.12.2: 2019-02-21
* Update to WordPress 5.1 ([#420](https://github.com/roots/bedrock/pull/420))
### 1.12.1: 2019-02-14
* Update `vlucas/phpdotenv` ([#417](https://github.com/roots/bedrock/pull/417))
* Make DSN implementation more uniform ([#415](https://github.com/roots/bedrock/pull/415))
### 1.12.0: 2019-02-07
* Support database DSN ([#414](https://github.com/roots/bedrock/pull/414))
* Detect HTTPS if WordPress is behind a reverse proxy ([#413](https://github.com/roots/bedrock/pull/413))
* Update `vlucas/phpdotenv` to `^3` ([#412](https://github.com/roots/bedrock/pull/412))
### 1.11.1: 2019-01-09
* Update to WordPress 5.0.3 ([#408](https://github.com/roots/bedrock/pull/408))
### 1.11.0: 2018-12-19
* Bump PHP requirement to >= 7.1 ([#405](https://github.com/roots/bedrock/pull/405))
### 1.10.2: 2018-12-19
* Update to WordPress 5.0.2 ([#406](https://github.com/roots/bedrock/pull/406))
### 1.10.1: 2018-12-12
* Update to WordPress 5.0.1 ([#403](https://github.com/roots/bedrock/pull/403))
### 1.10.0: 2018-12-09
* Update to WordPress 5.0, switch from `johnpbloch/wordpress` to `roots/wordpress` package ([#395](https://github.com/roots/bedrock/pull/395))
### 1.9.0: 2018-09-17
* Fix error display in development environments ([c457082](https://github.com/roots/bedrock/commit/c457082cf4b153400d3e34f4f68a30eea4cc7c38))
* --prefer-dist on roave/security-advisories ([#381](https://github.com/roots/bedrock/pull/381))
* New Bedrock Configuration Model ([#380](https://github.com/roots/bedrock/pull/380))
* Remove vendor/.gitkeep ([#379](https://github.com/roots/bedrock/pull/379))
* Composer 1.7.0 lockfile ([#378](https://github.com/roots/bedrock/pull/378))
* Adds roave/security-advisories to composer dev deps ([#376](https://github.com/roots/bedrock/pull/376))
### 1.8.12: 2018-08-03
* Update to WordPress 4.9.8
### 1.8.11: 2018-07-09
* Update to WordPress 4.9.7
### 1.8.10: 2018-05-18
* Update to WordPress 4.9.6
### 1.8.9: 2018-04-04
* Update to WordPress 4.9.5
### 1.8.8: 2018-02-06
* Update to WordPress 4.9.4
### 1.8.7: 2018-02-05
* Update to WordPress 4.9.3
### 1.8.6: 2018-01-16
* Update to WordPress 4.9.2
### 1.8.5: 2017-11-29
* Update to WordPress 4.9.1
### 1.8.4: 2017-11-16
* Update to WordPress 4.9.0
### 1.8.3: 2017-10-31
* Update to WordPress 4.8.3
### 1.8.2: 2017-09-19
* Update to WordPress 4.8.2
### 1.8.1: 2017-08-02
* Update to WordPress 4.8.1
### 1.8.0: 2017-06-08
* Update to WordPress 4.8.0
### 1.7.9: 2017-05-16
* Update to WordPress 4.7.5
### 1.7.8: 2017-05-03
* Update `johnpbloch/wordpress` to 4.7.4.1 (see https://github.com/johnpbloch/wordpress/issues/32)
### 1.7.7: 2017-04-20
* Update to WordPress 4.7.4
### 1.7.6: 2017-03-06
* Update to WordPress 4.7.3
### 1.7.5: 2017-01-26
* Update to WordPress 4.7.2
### 1.7.4: 2017-01-11
* Update to WordPress 4.7.1
* Add Optional variables to `.env.example`
* Remove unnecessary gitignore rules ([#286](https://github.com/roots/bedrock/pull/286))
### 1.7.3: 2016-12-06
* Update to WordPress 4.7
* Default `WP_ENV` to `production` instead of `development` ([#277](https://github.com/roots/bedrock/pull/277))
### 1.7.2: 2016-09-07
* Update to WordPress 4.6.1
### 1.7.1: 2016-08-16
* Update to WordPress 4.6
### 1.7.0: 2016-07-10
* Bump PHP requirement to >= 5.6 (5.5 is no longer supported)
### 1.6.4: 2016-06-21
* Update to WordPress 4.5.3
### 1.6.3: 2016-05-06
* Update to WordPress 4.5.2
### 1.6.2: 2016-04-26
* Update to WordPress 4.5.1
### 1.6.1: 2016-04-12
* Update to WordPress 4.5
* Update coding standards (PSR-2) ([#244](https://github.com/roots/bedrock/pull/244))
### 1.6.0: 2016-03-03
* Add wp-password-bcrypt for more secure passwords ([#243](https://github.com/roots/bedrock/pull/243))
### 1.5.4: 2016-02-29
* Use HTTPS for wpackagist.org
### 1.5.3: 2016-02-03
* Update to WordPress 4.4.2
### 1.5.2: 2016-02-01
* Bump `composer/installers` dependency to 1.0.23 to fix deprecation notice
### 1.5.1: 2016-01-27
* Use [oscarotero/env](https://github.com/oscarotero/env) instead of `getenv` ([#229](https://github.com/roots/bedrock/pull/233))
### 1.5.0: 2016-01-17
* Fix `DISABLE_WP_CRON` setting via ENV variable ([#229](https://github.com/roots/bedrock/pull/229))
* Set default `DB_CHARSET` to `utf8mb4`
### 1.4.7: 2016-01-07
* Update to WordPress 4.4.1
### 1.4.6: 2015-12-09
* Update to WordPress 4.4
### 1.4.5: 2015-09-16
* Update to WordPress 4.3.1
* Bump minimum required PHP version to 5.5 ([#201](https://github.com/roots/bedrock/pull/201))
### 1.4.4: 2015-08-18
* Update to WordPress 4.3
### 1.4.3: 2015-08-04
* Update to WordPress 4.2.4
### 1.4.2: 2015-07-24
* Update to WordPress 4.2.3
### 1.4.1: 2015-06-30
* Dotenv 2.0.1 update
### 1.4.0: 2015-06-07
* Removed .env generation script
### 1.3.7: 2015-05-07
* Update to WordPress 4.2.2
### 1.3.6: 2015-04-27
* Update to WordPress 4.2.1
### 1.3.5: 2015-04-23
* Update to WordPress 4.2
* Update to WordPress 4.1.2
* Don't register theme directory if `WP_DEFAULT_THEME` is defined
* Move Capistrano configs to https://github.com/roots/bedrock-capistrano
### 1.3.4: 2015-02-18
* WordPress 4.1.1 fix
### 1.3.3: 2015-02-18
* Update to WordPress 4.1.1
* mu-plugins autoloader Multisite fix
* Coding standards update + TravisCI integration
### 1.3.2: 2014-12-18
* Update to WordPress 4.1
* Remove WPLANG constant
### 1.3.1: 2014-11-28
* Add Capistrano task to fix/update WP theme paths after deploys
### 1.3.0: 2014-11-20
* Update to WordPress 4.0.1
* Use johnpbloch/wordpress package instead of custom repository
* Update default deploy.rb
* Require PHP >= 5.4 in composer.json
* Better PSR-1 adherence
* Update phpdotenv dependency to 1.0.9
* Fix Composer installer path plugin order
* Add bedrock-autoloader mu-plugin
### 1.2.7: 2014-09-04
* Update to WordPress 4.0
### 1.2.6: 2014-08-06
* Update to WordPress 3.9.2
* Minor deploy fix
* Doc updates
### 1.2.5: 2014-07-16
* Update to WordPress 3.9.1
* Doc updates
* Add `DB_PREFIX` constant
* Update Gem versions
* Disallow indexing in non-production environments
### 1.2.4: 2014-04-17
* Fixes issue with 3.9 update (`composer.lock` wasn't updated)
### 1.2.3: 2014-04-16
* Update to WordPress 3.9
### 1.2.2: 2014-04-14
* Update to WordPress 3.8.3
* Only run `Dotenv::load` if `.env` file exists
### 1.2.1: 2014-04-08
* Update to WordPress 3.8.2
### 1.2.0: 2014-04-07
* WP package now has `wordpress` vendor name: `wordpress/wordpress`
* Remove wp-cli and add `wp-cli.yml` config
### 1.1.1: 2014-03-11
* Update phpdotenv to 1.0.6
* Update wp-cli to v0.14.1
* Update README to refence new WordPress Packagist namespaces
* Fix uploads path in `linked_dirs` for Capistrano deploys
### 1.1.0: 2014-03-01
* Update to Capistrano 3.1.0: `deploy:restart` is no longer run by default
* Better webroot structure: introduces the `/web` directory as the document/web root for web server vhosts
### 1.0.0: 2013-12-18
* Initial release

19
LICENSE.md Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) Roots
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

115
README.md Normal file
View File

@ -0,0 +1,115 @@
<p align="center">
<a href="https://roots.io/bedrock/">
<img alt="Bedrock" src="https://cdn.roots.io/app/uploads/logo-bedrock.svg" height="100">
</a>
</p>
<p align="center">
<a href="LICENSE.md">
<img alt="MIT License" src="https://img.shields.io/github/license/roots/bedrock?color=%23525ddc&style=flat-square" />
</a>
<a href="https://packagist.org/packages/roots/bedrock">
<img alt="Packagist" src="https://img.shields.io/packagist/v/roots/bedrock.svg?style=flat-square" />
</a>
<a href="https://circleci.com/gh/roots/bedrock">
<img alt="Build Status" src="https://img.shields.io/circleci/build/gh/roots/bedrock?style=flat-square" />
</a>
<a href="https://twitter.com/rootswp">
<img alt="Follow Roots" src="https://img.shields.io/twitter/follow/rootswp.svg?style=flat-square&color=1da1f2" />
</a>
</p>
<p align="center">
<strong>A modern WordPress stack</strong>
<br />
Built with ❤️
</p>
<p align="center">
<a href="https://roots.io">Official Website</a> | <a href="https://roots.io/docs/bedrock/master/installation/">Documentation</a> | <a href="CHANGELOG.md">Change Log</a>
</p>
## Supporting
**Bedrock** is an open source project and completely free to use.
However, the amount of effort needed to maintain and develop new features and products within the Roots ecosystem is not sustainable without proper financial backing. If you have the capability, please consider donating using the links below:
<div align="center">
[![Donate via Patreon](https://img.shields.io/badge/donate-patreon-orange.svg?style=flat-square&logo=patreon")](https://www.patreon.com/rootsdev)
[![Donate via PayPal](https://img.shields.io/badge/donate-paypal-blue.svg?style=flat-square&logo=paypal)](https://www.paypal.me/rootsdev)
</div>
## Overview
Bedrock is a modern WordPress stack that helps you get started with the best development tools and project structure.
Much of the philosophy behind Bedrock is inspired by the [Twelve-Factor App](http://12factor.net/) methodology including the [WordPress specific version](https://roots.io/twelve-factor-wordpress/).
## Features
- Better folder structure
- Dependency management with [Composer](https://getcomposer.org)
- Easy WordPress configuration with environment specific files
- Environment variables with [Dotenv](https://github.com/vlucas/phpdotenv)
- Autoloader for mu-plugins (use regular plugins as mu-plugins)
- Enhanced security (separated web root and secure passwords with [wp-password-bcrypt](https://github.com/roots/wp-password-bcrypt))
## Requirements
- PHP >= 7.1
- Composer - [Install](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-osx)
## Installation
1. Create a new project:
```sh
$ composer create-project roots/bedrock
```
2. Update environment variables in the `.env` file. Wrap values that may contain non-alphanumeric characters with quotes, or they may be incorrectly parsed.
- Database variables
- `DB_NAME` - Database name
- `DB_USER` - Database user
- `DB_PASSWORD` - Database password
- `DB_HOST` - Database host
- Optionally, you can define `DATABASE_URL` for using a DSN instead of using the variables above (e.g. `mysql://user:password@127.0.0.1:3306/db_name`)
- `WP_ENV` - Set to environment (`development`, `staging`, `production`)
- `WP_HOME` - Full URL to WordPress home (https://example.com)
- `WP_SITEURL` - Full URL to WordPress including subdirectory (https://example.com/wp)
- `AUTH_KEY`, `SECURE_AUTH_KEY`, `LOGGED_IN_KEY`, `NONCE_KEY`, `AUTH_SALT`, `SECURE_AUTH_SALT`, `LOGGED_IN_SALT`, `NONCE_SALT`
- Generate with [wp-cli-dotenv-command](https://github.com/aaemnnosttv/wp-cli-dotenv-command)
- Generate with [our WordPress salts generator](https://roots.io/salts.html)
3. Add theme(s) in `web/app/themes/` as you would for a normal WordPress site
4. Set the document root on your webserver to Bedrock's `web` folder: `/path/to/site/web/`
5. Access WordPress admin at `https://example.com/wp/wp-admin/`
## Documentation
Bedrock documentation is available at [https://roots.io/docs/bedrock/master/installation/](https://roots.io/docs/bedrock/master/installation/).
## Contributing
Contributions are welcome from everyone. We have [contributing guidelines](https://github.com/roots/guidelines/blob/master/CONTRIBUTING.md) to help you get started.
## Bedrock sponsors
Help support our open-source development efforts by [becoming a patron](https://www.patreon.com/rootsdev).
<a href="https://kinsta.com/?kaid=OFDHAJIXUDIV"><img src="https://cdn.roots.io/app/uploads/kinsta.svg" alt="Kinsta" width="200" height="150"></a> <a href="https://k-m.com/"><img src="https://cdn.roots.io/app/uploads/km-digital.svg" alt="KM Digital" width="200" height="150"></a>
## Community
Keep track of development and community news.
- 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/)
- Listen to the [Roots Radio podcast](https://roots.io/podcast/)

72
composer.json Normal file
View File

@ -0,0 +1,72 @@
{
"name": "roots/bedrock",
"type": "project",
"license": "MIT",
"description": "WordPress boilerplate with modern development tools, easier configuration, and an improved folder structure",
"homepage": "https://roots.io/bedrock/",
"authors": [
{
"name": "Scott Walkinshaw",
"email": "scott.walkinshaw@gmail.com",
"homepage": "https://github.com/swalkinshaw"
},
{
"name": "Ben Word",
"email": "ben@benword.com",
"homepage": "https://github.com/retlehs"
}
],
"keywords": [
"bedrock", "composer", "roots", "wordpress", "wp", "wp-config"
],
"support": {
"issues": "https://github.com/roots/bedrock/issues",
"forum": "https://discourse.roots.io/category/bedrock"
},
"repositories": [
{
"type": "composer",
"url": "https://wpackagist.org",
"only": ["wpackagist-plugin/*", "wpackagist-theme/*"]
}
],
"require": {
"php": ">=7.1",
"composer/installers": "^1.8",
"vlucas/phpdotenv": "^4.1.3",
"oscarotero/env": "^1.2.0",
"roots/wordpress": "5.4.1",
"roots/wp-config": "1.0.0",
"roots/wp-password-bcrypt": "1.0.0",
"wpackagist-plugin/advanced-custom-fields": "^5.8",
"wpackagist-plugin/classic-editor": "^1.5",
"timber/timber": "^1.15",
"wpackagist-plugin/timber-library": "^1.15"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.5.4",
"roave/security-advisories": "dev-master"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist"
},
"minimum-stability": "dev",
"prefer-stable": true,
"extra": {
"installer-paths": {
"web/app/mu-plugins/{$name}/": ["type:wordpress-muplugin"],
"web/app/plugins/{$name}/": ["type:wordpress-plugin"],
"web/app/themes/{$name}/": ["type:wordpress-theme"]
},
"wordpress-install-dir": "web/wp"
},
"scripts": {
"post-root-package-install": [
"php -r \"copy('.env.example', '.env');\""
],
"test": [
"phpcs"
]
}
}

1336
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

134
config/application.php Normal file
View File

@ -0,0 +1,134 @@
<?php
/**
* Your base production configuration goes in this file. Environment-specific
* overrides go in their respective config/environments/{{WP_ENV}}.php file.
*
* A good default policy is to deviate from the production config as little as
* possible. Try to define as much of your configuration in this file as you
* can.
*/
use Roots\WPConfig\Config;
/**
* Directory containing all of the site's files
*
* @var string
*/
$root_dir = dirname(__DIR__);
/**
* Document Root
*
* @var string
*/
$webroot_dir = $root_dir . '/web';
/**
* Expose global env() function from oscarotero/env
*/
Env::init();
/**
* Use Dotenv to set required environment variables and load .env file in root
*/
$dotenv = Dotenv\Dotenv::createImmutable($root_dir);
if (file_exists($root_dir . '/.env')) {
$dotenv->load();
$dotenv->required(['WP_HOME', 'WP_SITEURL']);
if (!env('DATABASE_URL')) {
$dotenv->required(['DB_NAME', 'DB_USER', 'DB_PASSWORD']);
}
}
/**
* Set up our global environment constant and load its config first
* Default: production
*/
define('WP_ENV', env('WP_ENV') ?: 'production');
/**
* URLs
*/
Config::define('WP_HOME', env('WP_HOME'));
Config::define('WP_SITEURL', env('WP_SITEURL'));
/**
* Custom Content Directory
*/
Config::define('CONTENT_DIR', '/app');
Config::define('WP_CONTENT_DIR', $webroot_dir . Config::get('CONTENT_DIR'));
Config::define('WP_CONTENT_URL', Config::get('WP_HOME') . Config::get('CONTENT_DIR'));
/**
* DB settings
*/
Config::define('DB_NAME', env('DB_NAME'));
Config::define('DB_USER', env('DB_USER'));
Config::define('DB_PASSWORD', env('DB_PASSWORD'));
Config::define('DB_HOST', env('DB_HOST') ?: 'localhost');
Config::define('DB_CHARSET', 'utf8mb4');
Config::define('DB_COLLATE', '');
$table_prefix = env('DB_PREFIX') ?: 'wp_';
if (env('DATABASE_URL')) {
$dsn = (object) parse_url(env('DATABASE_URL'));
Config::define('DB_NAME', substr($dsn->path, 1));
Config::define('DB_USER', $dsn->user);
Config::define('DB_PASSWORD', isset($dsn->pass) ? $dsn->pass : null);
Config::define('DB_HOST', isset($dsn->port) ? "{$dsn->host}:{$dsn->port}" : $dsn->host);
}
/**
* Authentication Unique Keys and Salts
*/
Config::define('AUTH_KEY', env('AUTH_KEY'));
Config::define('SECURE_AUTH_KEY', env('SECURE_AUTH_KEY'));
Config::define('LOGGED_IN_KEY', env('LOGGED_IN_KEY'));
Config::define('NONCE_KEY', env('NONCE_KEY'));
Config::define('AUTH_SALT', env('AUTH_SALT'));
Config::define('SECURE_AUTH_SALT', env('SECURE_AUTH_SALT'));
Config::define('LOGGED_IN_SALT', env('LOGGED_IN_SALT'));
Config::define('NONCE_SALT', env('NONCE_SALT'));
/**
* Custom Settings
*/
Config::define('AUTOMATIC_UPDATER_DISABLED', true);
Config::define('DISABLE_WP_CRON', env('DISABLE_WP_CRON') ?: false);
// Disable the plugin and theme file editor in the admin
Config::define('DISALLOW_FILE_EDIT', true);
// Disable plugin and theme updates and installation from the admin
Config::define('DISALLOW_FILE_MODS', true);
/**
* Debugging Settings
*/
Config::define('WP_DEBUG_DISPLAY', false);
Config::define('WP_DEBUG_LOG', env('WP_DEBUG_LOG') ?? false);
Config::define('SCRIPT_DEBUG', false);
ini_set('display_errors', '0');
/**
* Allow WordPress to detect HTTPS when used behind a reverse proxy or a load balancer
* See https://codex.wordpress.org/Function_Reference/is_ssl#Notes
*/
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
$env_config = __DIR__ . '/environments/' . WP_ENV . '.php';
if (file_exists($env_config)) {
require_once $env_config;
}
Config::apply();
/**
* Bootstrap WordPress
*/
if (!defined('ABSPATH')) {
define('ABSPATH', $webroot_dir . '/wp/');
}

View File

@ -0,0 +1,17 @@
<?php
/**
* Configuration overrides for WP_ENV === 'development'
*/
use Roots\WPConfig\Config;
Config::define('SAVEQUERIES', true);
Config::define('WP_DEBUG', true);
Config::define('WP_DEBUG_DISPLAY', true);
Config::define('WP_DISABLE_FATAL_ERROR_HANDLER', true);
Config::define('SCRIPT_DEBUG', true);
ini_set('display_errors', '1');
// Enable plugin and theme updates and installation from the admin
Config::define('DISALLOW_FILE_MODS', false);

View File

@ -0,0 +1,15 @@
<?php
/**
* Configuration overrides for WP_ENV === 'staging'
*/
use Roots\WPConfig\Config;
/**
* You should try to keep staging as close to production as possible. However,
* should you need to, you can always override production configuration values
* with `Config::define`.
*
* Example: `Config::define('WP_DEBUG', true);`
* Example: `Config::define('DISALLOW_FILE_MODS', false);`
*/

23
phpcs.xml Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0"?>
<ruleset name="Roots">
<description>Roots Coding Standards</description>
<!-- Scan all files in directory -->
<file>.</file>
<!-- Scan only PHP files -->
<arg name="extensions" value="php"/>
<!-- Ignore WordPress and Composer dependencies -->
<exclude-pattern>web/wp</exclude-pattern>
<exclude-pattern>vendor/</exclude-pattern>
<!-- Show colors in console -->
<arg value="-colors"/>
<!-- Show sniff codes in all reports -->
<arg value="ns"/>
<!-- Use PSR-2 as a base -->
<rule ref="PSR2"/>
</ruleset>

View File

@ -0,0 +1,243 @@
<?php
/**
* Plugin Name: Bedrock Autoloader
* Plugin URI: https://github.com/roots/bedrock/
* Description: An autoloader that enables standard plugins to be required just like must-use plugins. The autoloaded plugins are included during mu-plugin loading. An asterisk (*) next to the name of the plugin designates the plugins that have been autoloaded.
* Version: 1.0.1
* Author: Roots
* Author URI: https://roots.io/
* License: MIT License
*/
namespace Roots\Bedrock;
if (!is_blog_installed()) {
return;
}
/**
* Class Autoloader
* @package Roots\Bedrock
* @author Roots
* @link https://roots.io/
*/
class Autoloader
{
/**
* Singleton instance.
*
* @var static
*/
private static $instance;
/**
* Store Autoloader cache and site option.
*
* @var array
*/
private $cache;
/**
* Autoloaded plugins.
*
* @var array
*/
private $autoPlugins;
/**
* Autoloaded mu-plugins.
*
* @var array
*/
private $muPlugins;
/**
* Number of plugins.
*
* @var int
*/
private $count;
/**
* Newly activated plugins.
*
* @var array
*/
private $activated;
/**
* Relative path to the mu-plugins directory.
*
* @var string
*/
private $relativePath;
/**
* Create an instance of Autoloader.
*
* @return void
*/
public function __construct()
{
if (isset(self::$instance)) {
return;
}
self::$instance = $this;
$this->relativePath = '/../' . basename(__DIR__);
if (is_admin()) {
add_filter('show_advanced_plugins', [$this, 'showInAdmin'], 0, 2);
}
$this->loadPlugins();
}
/**
* Run some checks then autoload our plugins.
*
* @return void
*/
public function loadPlugins()
{
$this->checkCache();
$this->validatePlugins();
$this->countPlugins();
array_map(static function () {
include_once WPMU_PLUGIN_DIR . '/' . func_get_args()[0];
}, array_keys($this->cache['plugins']));
$this->pluginHooks();
}
/**
* Filter show_advanced_plugins to display the autoloaded plugins.
*
* @param bool $show Whether to show the advanced plugins for the specified plugin type.
* @param string $type The plugin type, i.e., `mustuse` or `dropins`
* @return bool We return `false` to prevent WordPress from overriding our work
*/
public function showInAdmin($show, $type)
{
$screen = get_current_screen();
$current = is_multisite() ? 'plugins-network' : 'plugins';
if ($screen->base !== $current || $type !== 'mustuse' || !current_user_can('activate_plugins')) {
return $show;
}
$this->updateCache();
$this->autoPlugins = array_map(function ($auto_plugin) {
$auto_plugin['Name'] .= ' *';
return $auto_plugin;
}, $this->autoPlugins);
$GLOBALS['plugins']['mustuse'] = array_unique(array_merge($this->autoPlugins, $this->muPlugins), SORT_REGULAR);
return false;
}
/**
* This sets the cache or calls for an update
*
* @return void
*/
private function checkCache()
{
$cache = get_site_option('bedrock_autoloader');
if ($cache === false || (isset($cache['plugins'], $cache['count']) && count($cache['plugins']) !== $cache['count'])) {
$this->updateCache();
return;
}
$this->cache = $cache;
}
/**
* Update mu-plugin cache.
*
* Get the plugins and mu-plugins from the mu-plugin path and remove duplicates.
* Check cache against current plugins for newly activated plugins.
* After that, we can update the cache.
*
* @return void
*/
private function updateCache()
{
require_once ABSPATH . 'wp-admin/includes/plugin.php';
$this->autoPlugins = get_plugins($this->relativePath);
$this->muPlugins = get_mu_plugins();
$plugins = array_diff_key($this->autoPlugins, $this->muPlugins);
$rebuild = !(isset($this->cache['plugins']) && is_array($this->cache['plugins']));
$this->activated = $rebuild ? $plugins : array_diff_key($plugins, $this->cache['plugins']);
$this->cache = ['plugins' => $plugins, 'count' => $this->countPlugins()];
update_site_option('bedrock_autoloader', $this->cache);
}
/**
* Activate plugin hooks.
*
* This accounts for the plugin hooks that would run if the plugins were
* loaded as usual. Plugins are removed by deletion, so there's no way
* to deactivate or uninstall.
*
* @return void
*/
private function pluginHooks()
{
if (!is_array($this->activated)) {
return;
}
foreach ($this->activated as $plugin_file => $plugin_info) {
do_action('activate_' . $plugin_file);
}
}
/**
* Check that the plugin file exists, if it doesn't update the cache.
*
* @return void
*/
private function validatePlugins()
{
foreach ($this->cache['plugins'] as $plugin_file => $plugin_info) {
if (!file_exists(WPMU_PLUGIN_DIR . '/' . $plugin_file)) {
$this->updateCache();
break;
}
}
}
/**
* Count the number of autoloaded plugins.
*
* Count our plugins (but only once) by counting the top level folders in the
* mu-plugins dir. If it's more or less than last time, update the cache.
*
* @return int Number of autoloaded plugins.
*/
private function countPlugins()
{
if (isset($this->count)) {
return $this->count;
}
$count = count(glob(WPMU_PLUGIN_DIR . '/*/', GLOB_ONLYDIR | GLOB_NOSORT));
if (!isset($this->cache['count']) || $count !== $this->cache['count']) {
$this->count = $count;
$this->updateCache();
}
return $this->count;
}
}
new Autoloader();

View File

@ -0,0 +1,14 @@
<?php
/**
* Plugin Name: Disallow Indexing
* Plugin URI: https://github.com/roots/bedrock/
* Description: Disallow indexing of your site on non-production environments.
* Version: 1.0.0
* Author: Roots
* Author URI: https://roots.io/
* License: MIT License
*/
if (defined('WP_ENV') && WP_ENV !== 'production' && !is_admin()) {
add_action('pre_option_blog_public', '__return_zero');
}

View File

@ -0,0 +1,14 @@
<?php
/**
* Plugin Name: Register Theme Directory
* Plugin URI: https://github.com/roots/bedrock/
* Description: Register default theme directory
* Version: 1.0.0
* Author: Roots
* Author URI: https://roots.io/
* License: MIT License
*/
if (!defined('WP_DEFAULT_THEME')) {
register_theme_directory(ABSPATH . 'wp-content/themes');
}

0
web/app/plugins/.gitkeep Normal file
View File

0
web/app/themes/.gitkeep Normal file
View File

3
web/app/themes/la_mine/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
vendor
wp-content
composer.lock

View File

@ -0,0 +1,22 @@
sudo: false
dist: xenial
services: mysql
language: php
php:
- 5.6.30
- 7.3
env:
- WP_VERSION=latest WP_MULTISITE=0
- WP_VERSION=latest WP_MULTISITE=1
before_script:
- bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION
- composer install
script:
- vendor/phpunit/phpunit/phpunit

13
web/app/themes/la_mine/404.php Executable file
View File

@ -0,0 +1,13 @@
<?php
/**
* The template for displaying 404 pages (Not Found)
*
* Methods for TimberHelper can be found in the /functions sub-directory
*
* @package WordPress
* @subpackage Timber
* @since Timber 0.1
*/
$context = Timber::context();
Timber::render( '404.twig', $context );

7
web/app/themes/la_mine/LICENSE Executable file
View File

@ -0,0 +1,7 @@
Copyright (c) 2012-2013 Jared Novack
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,35 @@
# The Timber Starter Theme
The "_s" for Timber: a dead-simple theme that you can build from. The primary purpose of this theme is to provide a file structure rather than a framework for markup or styles. Configure your Sass, scripts, and task runners however you would like!
[![Build Status](https://travis-ci.org/timber/starter-theme.svg)](https://travis-ci.org/timber/starter-theme)
## Installing the Theme
Install this theme as you would any other, and be sure the Timber plugin is activated. But hey, let's break it down into some bullets:
1. Make sure you have installed the plugin for the [Timber Library](https://wordpress.org/plugins/timber-library/) (and Advanced Custom Fields - they [play quite nicely](https://timber.github.io/docs/guides/acf-cookbook/#nav) together).
2. Download the zip for this theme (or clone it) and move it to `wp-content/themes` in your WordPress installation.
3. Rename the folder to something that makes sense for your website (generally no spaces and all lowercase). You could keep the name `timber-starter-theme` but the point of a starter theme is to make it your own!
4. Activate the theme in Appearance > Themes.
5. Do your thing! And read [the docs](https://github.com/jarednova/timber/wiki).
## What's here?
`static/` is where you can keep your static front-end scripts, styles, or images. In other words, your Sass files, JS files, fonts, and SVGs would live here.
`templates/` contains all of your Twig templates. These pretty much correspond 1 to 1 with the PHP files that respond to the WordPress template hierarchy. At the end of each PHP template, you'll notice a `Timber::render()` function whose first parameter is the Twig file where that data (or `$context`) will be used. Just an FYI.
`bin/` and `tests/` ... basically don't worry about (or remove) these unless you know what they are and want to.
## Other Resources
The [main Timber Wiki](https://github.com/jarednova/timber/wiki) is super great, so reference those often. Also, check out these articles and projects for more info:
* [This branch](https://github.com/laras126/timber-starter-theme/tree/tackle-box) of the starter theme has some more example code with ACF and a slightly different set up.
* [Twig for Timber Cheatsheet](http://notlaura.com/the-twig-for-timber-cheatsheet/)
* [Timber and Twig Reignited My Love for WordPress](https://css-tricks.com/timber-and-twig-reignited-my-love-for-wordpress/) on CSS-Tricks
* [A real live Timber theme](https://github.com/laras126/yuling-theme).
* [Timber Video Tutorials](http://timber.github.io/timber/#video-tutorials) and [an incomplete set of screencasts](https://www.youtube.com/playlist?list=PLuIlodXmVQ6pkqWyR6mtQ5gQZ6BrnuFx-) for building a Timber theme from scratch.

View File

@ -0,0 +1,11 @@
<?php
/**
* Template Name: agenda
*/
$context = Timber::context();
$timber_post = new Timber\Post();
$context['post'] = $timber_post;
Timber::render( array( 'page-' . $timber_post->post_name . '.twig', 'page.twig' ), $context );

View File

@ -0,0 +1,40 @@
<?php
/**
* The template for displaying Archive pages.
*
* Used to display archive-type pages if nothing more specific matches a query.
* For example, puts together date-based pages if no date.php file exists.
*
* Learn more: http://codex.wordpress.org/Template_Hierarchy
*
* Methods for TimberHelper can be found in the /lib sub-directory
*
* @package WordPress
* @subpackage Timber
* @since Timber 0.2
*/
$templates = array( 'archive.twig', 'index.twig' );
$context = Timber::context();
$context['title'] = 'Archive';
if ( is_day() ) {
$context['title'] = 'Archive: ' . get_the_date( 'D M Y' );
} elseif ( is_month() ) {
$context['title'] = 'Archive: ' . get_the_date( 'M Y' );
} elseif ( is_year() ) {
$context['title'] = 'Archive: ' . get_the_date( 'Y' );
} elseif ( is_tag() ) {
$context['title'] = single_tag_title( '', false );
} elseif ( is_category() ) {
$context['title'] = single_cat_title( '', false );
array_unshift( $templates, 'archive-' . get_query_var( 'cat' ) . '.twig' );
} elseif ( is_post_type_archive() ) {
$context['title'] = post_type_archive_title( '', false );
array_unshift( $templates, 'archive-' . get_post_type() . '.twig' );
}
$context['posts'] = new Timber\PostQuery();
Timber::render( $templates, $context );

View File

@ -0,0 +1,21 @@
<?php
/**
* The template for displaying Author Archive pages
*
* Methods for TimberHelper can be found in the /lib sub-directory
*
* @package WordPress
* @subpackage Timber
* @since Timber 0.1
*/
global $wp_query;
$context = Timber::context();
$context['posts'] = new Timber\PostQuery();
if ( isset( $wp_query->query_vars['author'] ) ) {
$author = new Timber\User( $wp_query->query_vars['author'] );
$context['author'] = $author;
$context['title'] = 'Author Archives: ' . $author->name();
}
Timber::render( array( 'author.twig', 'archive.twig' ), $context );

View File

@ -0,0 +1,152 @@
#!/usr/bin/env bash
if [ $# -lt 3 ]; then
echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version] [skip-database-creation]"
exit 1
fi
DB_NAME=$1
DB_USER=$2
DB_PASS=$3
DB_HOST=${4-localhost}
WP_VERSION=${5-latest}
SKIP_DB_CREATE=${6-false}
TMPDIR=${TMPDIR-/tmp}
TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//")
WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib}
WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress/}
download() {
if [ `which curl` ]; then
curl -s "$1" > "$2";
elif [ `which wget` ]; then
wget -nv -O "$2" "$1"
fi
}
if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+$ ]]; then
WP_TESTS_TAG="branches/$WP_VERSION"
elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then
if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
# version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x
WP_TESTS_TAG="tags/${WP_VERSION%??}"
else
WP_TESTS_TAG="tags/$WP_VERSION"
fi
elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
WP_TESTS_TAG="trunk"
else
# http serves a single offer, whereas https serves multiple. we only want one
download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json
grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json
LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//')
if [[ -z "$LATEST_VERSION" ]]; then
echo "Latest WordPress version could not be found"
exit 1
fi
WP_TESTS_TAG="tags/$LATEST_VERSION"
fi
set -ex
install_wp() {
if [ -d $WP_CORE_DIR ]; then
return;
fi
mkdir -p $WP_CORE_DIR
if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
mkdir -p $TMPDIR/wordpress-nightly
download https://wordpress.org/nightly-builds/wordpress-latest.zip $TMPDIR/wordpress-nightly/wordpress-nightly.zip
unzip -q $TMPDIR/wordpress-nightly/wordpress-nightly.zip -d $TMPDIR/wordpress-nightly/
mv $TMPDIR/wordpress-nightly/wordpress/* $WP_CORE_DIR
else
if [ $WP_VERSION == 'latest' ]; then
local ARCHIVE_NAME='latest'
elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+ ]]; then
# https serves multiple offers, whereas http serves single.
download https://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json
if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
# version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x
LATEST_VERSION=${WP_VERSION%??}
else
# otherwise, scan the releases and get the most up to date minor version of the major release
local VERSION_ESCAPED=`echo $WP_VERSION | sed 's/\./\\\\./g'`
LATEST_VERSION=$(grep -o '"version":"'$VERSION_ESCAPED'[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//' | head -1)
fi
if [[ -z "$LATEST_VERSION" ]]; then
local ARCHIVE_NAME="wordpress-$WP_VERSION"
else
local ARCHIVE_NAME="wordpress-$LATEST_VERSION"
fi
else
local ARCHIVE_NAME="wordpress-$WP_VERSION"
fi
download https://wordpress.org/${ARCHIVE_NAME}.tar.gz $TMPDIR/wordpress.tar.gz
tar --strip-components=1 -zxmf $TMPDIR/wordpress.tar.gz -C $WP_CORE_DIR
fi
download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php
}
install_test_suite() {
# portable in-place argument for both GNU sed and Mac OSX sed
if [[ $(uname -s) == 'Darwin' ]]; then
local ioption='-i .bak'
else
local ioption='-i'
fi
# set up testing suite if it doesn't yet exist
if [ ! -d $WP_TESTS_DIR ]; then
# set up testing suite
mkdir -p $WP_TESTS_DIR
svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes
svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data
fi
if [ ! -f wp-tests-config.php ]; then
download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
# remove all forward slashes in the end
WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::")
sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
fi
}
install_db() {
if [ ${SKIP_DB_CREATE} = "true" ]; then
return 0
fi
# parse DB_HOST for port or socket references
local PARTS=(${DB_HOST//\:/ })
local DB_HOSTNAME=${PARTS[0]};
local DB_SOCK_OR_PORT=${PARTS[1]};
local EXTRA=""
if ! [ -z $DB_HOSTNAME ] ; then
if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then
EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
elif ! [ -z $DB_SOCK_OR_PORT ] ; then
EXTRA=" --socket=$DB_SOCK_OR_PORT"
elif ! [ -z $DB_HOSTNAME ] ; then
EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
fi
fi
# create database
mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
}
install_wp
install_test_suite
install_db

View File

@ -0,0 +1,24 @@
{
"name": "upstatement/timber-starter-theme",
"description": "Starter theme to build a Timber theme",
"type":"wordpress-theme",
"minimum-stability" : "stable",
"authors": [
{
"email": "jared@upstatement.com",
"name": "jarednova"
}
],
"repositories": [
{
"type": "composer",
"url": "https://wpackagist.org"
}
],
"require": {
"timber/timber": "1.*"
},
"require-dev": {
"phpunit/phpunit": "5.7.16|6.*"
}
}

View File

@ -0,0 +1,21 @@
<?php
/**
* Third party plugins that hijack the theme will call wp_footer() to get the footer template.
* We use this to end our output buffer (started in header.php) and render into the view/page-plugin.twig template.
*
* If you're not using a plugin that requries this behavior (ones that do include Events Calendar Pro and
* WooCommerce) you can delete this file and header.php
*
* @package WordPress
* @subpackage Timber
* @since Timber 0.1
*/
$timberContext = $GLOBALS['timberContext']; // @codingStandardsIgnoreFile
if ( ! isset( $timberContext ) ) {
throw new \Exception( 'Timber context not set in footer.' );
}
$timberContext['content'] = ob_get_contents();
ob_end_clean();
$templates = array( 'page-plugin.twig' );
Timber::render( $templates, $timberContext );

View File

@ -0,0 +1,167 @@
<?php
/**
* Timber starter-theme
* https://github.com/timber/starter-theme
*
* @package WordPress
* @subpackage Timber
* @since Timber 0.1
*/
/**
* If you are installing Timber as a Composer dependency in your theme, you'll need this block
* to load your dependencies and initialize Timber. If you are using Timber via the WordPress.org
* plug-in, you can safely delete this block.
*/
$composer_autoload = __DIR__ . '/vendor/autoload.php';
if ( file_exists( $composer_autoload ) ) {
require_once $composer_autoload;
$timber = new Timber\Timber();
}
/**
* This ensures that Timber is loaded and available as a PHP class.
* If not, it gives an error message to help direct developers on where to activate
*/
if ( ! class_exists( 'Timber' ) ) {
add_action(
'admin_notices',
function() {
echo '<div class="error"><p>Timber not activated. Make sure you activate the plugin in <a href="' . esc_url( admin_url( 'plugins.php#timber' ) ) . '">' . esc_url( admin_url( 'plugins.php' ) ) . '</a></p></div>';
}
);
add_filter(
'template_include',
function( $template ) {
return get_stylesheet_directory() . '/static/no-timber.html';
}
);
return;
}
/**
* Sets the directories (inside your theme) to find .twig files
*/
Timber::$dirname = array( 'templates', 'views' );
/**
* By default, Timber does NOT autoescape values. Want to enable Twig's autoescape?
* No prob! Just set this value to true
*/
Timber::$autoescape = false;
/**
* We're going to configure our theme inside of a subclass of Timber\Site
* You can move this to its own file and include here via php's include("MySite.php")
*/
class StarterSite extends Timber\Site {
/** Add timber support. */
public function __construct() {
add_action( 'after_setup_theme', array( $this, 'theme_supports' ) );
add_filter( 'timber/context', array( $this, 'add_to_context' ) );
add_filter( 'timber/twig', array( $this, 'add_to_twig' ) );
add_action( 'init', array( $this, 'register_post_types' ) );
add_action( 'init', array( $this, 'register_taxonomies' ) );
parent::__construct();
}
/** This is where you can register custom post types. */
public function register_post_types() {
}
/** This is where you can register custom taxonomies. */
public function register_taxonomies() {
}
/** This is where you add some context
*
* @param string $context context['this'] Being the Twig's {{ this }}.
*/
public function add_to_context( $context ) {
$context['foo'] = 'bar';
$context['stuff'] = 'I am a value set in your functions.php file';
$context['notes'] = 'These values are available everytime you call Timber::context();';
$context['menu'] = new Timber\Menu();
$context['site'] = $this;
return $context;
}
public function theme_supports() {
// Add default posts and comments RSS feed links to head.
add_theme_support( 'automatic-feed-links' );
/*
* Let WordPress manage the document title.
* By adding theme support, we declare that this theme does not use a
* hard-coded <title> tag in the document head, and expect WordPress to
* provide it for us.
*/
add_theme_support( 'title-tag' );
/*
* Enable support for Post Thumbnails on posts and pages.
*
* @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/
*/
add_theme_support( 'post-thumbnails' );
/*
* Switch default core markup for search form, comment form, and comments
* to output valid HTML5.
*/
add_theme_support(
'html5',
array(
'comment-form',
'comment-list',
'gallery',
'caption',
)
);
/*
* Enable support for Post Formats.
*
* See: https://codex.wordpress.org/Post_Formats
*/
add_theme_support(
'post-formats',
array(
'aside',
'image',
'video',
'quote',
'link',
'gallery',
'audio',
)
);
add_theme_support( 'menus' );
}
/** This Would return 'foo bar!'.
*
* @param string $text being 'foo', then returned 'foo bar!'.
*/
public function myfoo( $text ) {
$text .= ' bar!';
return $text;
}
/** This is where you can add your own functions to twig.
*
* @param string $twig get extension.
*/
public function add_to_twig( $twig ) {
$twig->addExtension( new Twig\Extension\StringLoaderExtension() );
$twig->addFilter( new Twig\TwigFilter( 'myfoo', array( $this, 'myfoo' ) ) );
return $twig;
}
}
new StarterSite();

View File

@ -0,0 +1,15 @@
<?php
/**
* Third party plugins that hijack the theme will call wp_head() to get the header template.
* We use this to start our output buffer and render into the view/page-plugin.twig template in footer.php
*
* If you're not using a plugin that requries this behavior (ones that do include Events Calendar Pro and
* WooCommerce) you can delete this file and footer.php
*
* @package WordPress
* @subpackage Timber
* @since Timber 0.1
*/
$GLOBALS['timberContext'] = Timber::context();
ob_start();

View File

@ -0,0 +1,10 @@
## Team
Your name or company
http://yoursite.org
@you_on_twitter
## Site
Software: Built with [Timber](http://upstatement.com/timber) by Upstatement

View File

@ -0,0 +1,23 @@
<?php
/**
* The main template file
* This is the most generic template file in a WordPress theme
* and one of the two required files for a theme (the other being style.css).
* It is used to display a page when nothing more specific matches a query.
* E.g., it puts together the home page when no home.php file exists
*
* Methods for TimberHelper can be found in the /lib sub-directory
*
* @package WordPress
* @subpackage Timber
* @since Timber 0.1
*/
$context = Timber::context();
$context['posts'] = new Timber\PostQuery();
$context['foo'] = 'bar';
$templates = array( 'index.twig' );
if ( is_home() ) {
array_unshift( $templates, 'front-page.twig', 'home.twig' );
}
Timber::render( $templates, $context );

28
web/app/themes/la_mine/page.php Executable file
View File

@ -0,0 +1,28 @@
<?php
/**
* The template for displaying all pages.
*
* This is the template that displays all pages by default.
* Please note that this is the WordPress construct of pages
* and that other 'pages' on your WordPress site will use a
* different template.
*
* To generate specific templates for your pages you can use:
* /mytheme/templates/page-mypage.twig
* (which will still route through this PHP file)
* OR
* /mytheme/page-mypage.php
* (in which case you'll want to duplicate this file and save to the above path)
*
* Methods for TimberHelper can be found in the /lib sub-directory
*
* @package WordPress
* @subpackage Timber
* @since Timber 0.1
*/
$context = Timber::context();
$timber_post = new Timber\Post();
$context['post'] = $timber_post;
Timber::render( array( 'page-' . $timber_post->post_name . '.twig', 'page.twig' ), $context );

View File

@ -0,0 +1,20 @@
<phpunit
bootstrap="tests/bootstrap.php"
backupGlobals="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
>
<testsuites>
<testsuite>
<directory prefix="test-" suffix=".php">./tests/</directory>
</testsuite>
<!-- The suite below HAS to be last to run,
as it includes a test that sets some const and would contaminate
the other tests as well. -->
<testsuite>
<directory prefix="testX-" suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
</phpunit>

View File

@ -0,0 +1,11 @@
<?php
/**
* Template Name: projets
*/
$context = Timber::context();
$timber_post = new Timber\Post();
$context['post'] = $timber_post;
Timber::render( array( 'page-' . $timber_post->post_name . '.twig', 'page.twig' ), $context );

View File

@ -0,0 +1,18 @@
<?php
/**
* Search results page
*
* Methods for TimberHelper can be found in the /lib sub-directory
*
* @package WordPress
* @subpackage Timber
* @since Timber 0.1
*/
$templates = array( 'search.twig', 'archive.twig', 'index.twig' );
$context = Timber::context();
$context['title'] = 'Search results for ' . get_search_query();
$context['posts'] = new Timber\PostQuery();
Timber::render( $templates, $context );

View File

@ -0,0 +1,9 @@
<?php
/**
* The Template for the sidebar containing the main widget area
*
* @package WordPress
* @subpackage Timber
*/
Timber::render( array( 'sidebar.twig' ), $data );

View File

@ -0,0 +1,20 @@
<?php
/**
* The Template for displaying all single posts
*
* Methods for TimberHelper can be found in the /lib sub-directory
*
* @package WordPress
* @subpackage Timber
* @since Timber 0.1
*/
$context = Timber::context();
$timber_post = Timber::query_post();
$context['post'] = $timber_post;
if ( post_password_required( $timber_post->ID ) ) {
Timber::render( 'single-password.twig', $context );
} else {
Timber::render( array( 'single-' . $timber_post->ID . '.twig', 'single-' . $timber_post->post_type . '.twig', 'single-' . $timber_post->slug . '.twig', 'single.twig' ), $context );
}

View File

@ -0,0 +1,10 @@
<!doctype html>
<html lang="en">
<head>
<title>Timber not active</title>
</head>
<body>
<p>Timber not activated</p>
</body>
</html>

View File

@ -0,0 +1,5 @@
jQuery( document ).ready( function( $ ) {
// Your JavaScript goes here
});

View File

@ -0,0 +1,5 @@
/*
* Theme Name: My Timber Starter Theme
* Description: Starter Theme to use with Timber
* Author: Upstatement and YOU!
*/

View File

@ -0,0 +1,5 @@
{% extends "base.twig" %}
{% block content %}
Sorry, we couldn't find what you're looking for.
{% endblock %}

View File

@ -0,0 +1,9 @@
{# This file demonstrates using most of the index.twig template and modifying
just a small part. See `search.twig` for an example of another approach #}
{% extends "index.twig" %}
{% block content %}
<h3>This is my archive</h3>
{{ parent() }}
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends "base.twig" %}
{% block content %}
{% for post in posts %}
{% include ["tease-"~post.post_type~".twig", "tease.twig"] %}
{% endfor %}
{% endblock %}

View File

@ -0,0 +1,45 @@
{% block html_head_container %}
{% include 'html-header.twig' %}
{% block head %}
{% endblock %}
</head>
{% endblock %}
<body class="{{body_class}}" data-template="base.twig">
<a class="skip-link screen-reader-text" href="#content">{{ _e( 'Skip to content') }}</a>
<header class="header" >
{% block header %}
<div class="wrapper">
<h1 class="hdr-logo" role="banner">
<a class="hdr-logo-link" href="{{site.url}}" rel="home">{{site.name}}</a>
</h1>
<nav id="nav-main" class="nav-main" role="navigation">
{% include "menu.twig" with {'items': menu.get_items} %}
</nav><!-- #nav -->
</div>
{% endblock %}
</header>
<section id="content" role="main" class="content-wrapper">
{% if title %}<h1>{{title}}</h1>{% endif %}
<div class="wrapper {{sidebar_class}}">
{% block content %}
Sorry, no content
{% endblock %}
</div>
{% if sidebar %}
<aside class="layout-sidebar">
{{sidebar}}
</aside>
{% endif %}
</section>
{% block footer %}
<footer id="footer">
{% include 'footer.twig' %}
</footer>
{{ function('wp_footer') }}
{% endblock %}
</body>
</html>

View File

@ -0,0 +1,28 @@
<div class="comment-form">
<h3>Add comment</h3>
<form class="comment-form" method="post" action="{{ site.site_url~'/wp-comments-post.php' }}">
{% if user %}
<input type="hidden" name="email" value="{{ user.email }}">
<input type="hidden" name="author" value="{{ user.name }}">
<input type="hidden" name="url" value="{{ user.link }}">
{% else %}
<label>Email<br>
<input required name="email" type="email" id="email">
</label>
<label>Name<br>
<input required name="author" type="text">
</label>
<label>Website<br>
<input name="url" type="url">
</label>
{% endif %}
<label>Comment<br>
<textarea placeholder="Leave a comment..." name="comment" cols="60" rows="3"></textarea>
</label>
<input name="comment_post_ID" value="{{ post.id }}" type="hidden">
<input name="comment_parent" value="{{ comment.ID|default('0') }}" type="hidden">
<button type="submit" name="Submit" class="btn">Send</button>
<button type="reset">Cancel</button>
<p>Your comment will be revised by the site if needed.</p>
</form>
</div>

View File

@ -0,0 +1,21 @@
<div class="blog-comment {{comment.comment_type}}" id="blog-comment-{{comment.ID}}">
<h5 class="comment-author">{{comment.author.name}} says</h5>
<div class="comment-content">{{comment.comment_content|wpautop}}</div>
<section class="comment-box">
<!-- comment form -->
{% include "comment-form.twig" %}
<!-- child comments -->
{% if post.comments %}
<h4> replies </h4>
<div class="comments">
{% for cmt in comment.children %}
{% include "comment.twig" with {comment:cmt} %}
{% endfor %}
</div>
{% endif %}
</section>
</div>

View File

@ -0,0 +1 @@
Copyright {{"now"|date('Y')}}

View File

@ -0,0 +1,15 @@
<!doctype html>
<!--[if lt IE 9]><html class="no-js no-svg ie lt-ie9 lt-ie8 lt-ie7" {{ site.language_attributes }}> <![endif]-->
<!--[if IE 9]><html class="no-js no-svg ie ie9 lt-ie9 lt-ie8" {{ site.language_attributes }}> <![endif]-->
<!--[if gt IE 9]><!--><html class="no-js no-svg" {{ site.language_attributes }}> <!--<![endif]-->
<head>
<meta charset="{{ site.charset }}" />
<meta name="description" content="{{ site.description }}">
<link rel="stylesheet" href="{{ site.theme.link }}/style.css" type="text/css" media="screen" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="author" href="{{ site.theme.link }}/humans.txt" />
<link rel="pingback" href="{{ site.pingback_url }}" />
<link rel="profile" href="http://gmpg.org/xfn/11">
{{function('wp_head')}}

View File

@ -0,0 +1,11 @@
{% extends "base.twig" %}
{% block content %}
<h2>{{ foo }}</h2>
<p>{{ qux }}</p>
{% for post in posts %}
{% include ['tease-'~post.post_type~'.twig', 'tease.twig'] %}
{% endfor %}
{% include 'partial/pagination.twig' with { pagination: posts.pagination({show_all: false, mid_size: 3, end_size: 2}) } %}
{% endblock %}

View File

@ -0,0 +1,10 @@
{% if menu %}
<ul>
{% for item in items %}
<li class="{{ item.classes | join(' ') }}">
<a target="{{ item.target }}" href="{{ item.link }}">{{ item.title }}</a>
{% include "menu.twig" with {'items': item.children} %}
</li>
{% endfor %}
</ul>
{% endif %}

View File

@ -0,0 +1,7 @@
{% extends "base.twig" %}
{% block content %}
<div class="container content-wrapper">
{{content}}
</div><!-- /content-wrapper -->
{% endblock %}

View File

@ -0,0 +1,14 @@
{% extends "base.twig" %}
{% block content %}
<div class="content-wrapper">
<article class="post-type-{{post.post_type}}" id="post-{{post.ID}}">
<section class="article-content">
<h1 class="article-h1">{{post.title}}</h1>
<div class="article-body">
{{post.content}}
</div>
</section>
</article>
</div><!-- /content-wrapper -->
{% endblock %}

View File

@ -0,0 +1,64 @@
{% if posts.pagination.pages is not empty %}
<nav class="pagination-block">
<ul class="pagination">
{# First #}
{% if posts.pagination.pages|first and posts.pagination.pages|first.current != true %}
<li class="first btn">
<a href="{{ posts.pagination.pages|first.link }}">First</a>
</li>
{% else %}
<li class="first btn disabled">
<button disabled>First</button>
</li>
{% endif %}
{# Previous #}
{% if posts.pagination.prev %}
<li class="prev btn">
<a href="{{ posts.pagination.prev.link }}">Previous</a>
</li>
{% else %}
<li class="prev btn disabled">
<button disabled>Previous</button>
</li>
{% endif %}
{# Pages #}
{% for page in posts.pagination.pages %}
{% if page.link %}
<li>
<a href="{{ page.link }}" class="{{ page.class }}">{{ page.title }}</a>
</li>
{% else %}
<li class="current">
<span class="{{ page.class }}">{{ page.title }}</span>
</li>
{% endif %}
{% endfor %}
{# Next #}
{% if posts.pagination.next %}
<li class="next btn">
<a href="{{ posts.pagination.next.link }}">Next</a>
</li>
{% else %}
<li class="next btn disabled">
<button disabled>Next</button>
</li>
{% endif %}
{# Last #}
{% if posts.pagination.pages|last and posts.pagination.pages|last.current != true %}
<li class="last btn">
<a href="{{ posts.pagination.pages|last.link }}">Last</a>
</li>
{% else %}
<li class="last btn disabled">
<button disabled>Last</button>
</li>
{% endif %}
</ul>
</nav>
{% endif %}

View File

@ -0,0 +1,13 @@
{# see `archive.twig` for an alternative strategy of extending templates #}
{% extends "base.twig" %}
{% block content %}
{# see `base.twig:27` for where this block's content will be inserted #}
<div class="content-wrapper">
{% for post in posts %}
{% include ['tease-'~post.post_type~'.twig', 'tease.twig'] %}
{% endfor %}
{% include 'partial/pagination.twig' with { pagination: posts.pagination({show_all: false, mid_size: 3, end_size: 2}) } %}
</div>
{% endblock %}

View File

@ -0,0 +1 @@
Sidebar in Timber. Add HTML to your hearts content.

View File

@ -0,0 +1,9 @@
{% extends "base.twig" %}
{% block content %}
<form class="password-form" action="{{site.site_url}}/wp-login.php?action=postpass" method="post">
<label for="pwbox-{{post.ID}}">Password:</label>
<input class="password-box" name="post_password" id="pwbox-{{post.ID}}" type="password" placeholder="Password" size="20" maxlength="20" />
<input class="password-btn" type="submit" name="Submit" value="Submit" />
</form>
{% endblock %}

View File

@ -0,0 +1,39 @@
{% extends "base.twig" %}
{% block content %}
<div class="content-wrapper">
<article class="post-type-{{ post.post_type }}" id="post-{{ post.ID }}">
<img src="{{ post.thumbnail.src|resize(1200, 300) }}">
<section class="article-content">
<h1 class="article-h1">{{ post.title }}</h1>
<a href="{{ post.link }}">{{ _e('edit') }}</a>
<p class="blog-author">
<span>By</span><a href="{{post.author.path}}"> {{ post.author.name }} </a><span>&bull;</span> <time datetime="{{ post.date|date('Y-m-d H:i:s') }}">{{ post.date }}</time>
</p>
<div class="article-body">
{{post.content}}
</div>
</section>
<!-- comment box -->
<section class="comment-box">
<!-- comments -->
<div class="comments">
{% if post.comments %}
<h3> comments </h3>
{% for cmt in post.comments %}
{% include "comment.twig" with {comment:cmt} %}
{% endfor %}
{% endif %}
</div>
{% if post.comment_status == "closed" %}
<p> comments for this post are closed </p>
{% else %}
<!-- comment form -->
{% include "comment-form.twig" %}
{% endif %}
</section>
</article>
</div><!-- /content-wrapper -->
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "tease.twig" %}
{% block content %}
<h2 class="h2"><a href="{{post.link}}">{{post.title}}</a></h2>
<p>{{post.preview.length(25)}}</p>
{% if post.thumbnail.src %}
<img src="{{post.thumbnail.src}}" />
{% endif %}
{% endblock %}

View File

@ -0,0 +1,9 @@
<article class="tease tease-{{post.post_type}}" id="tease-{{post.ID}}">
{% block content %}
<h2 class="h2"><a href="{{post.link}}">{{post.title}}</a></h2>
<p>{{post.preview}}</p>
{% if post.get_thumbnail %}
<img src="{{post.thumbnail.src}}" />
{% endif %}
{% endblock %}
</article>

View File

@ -0,0 +1,22 @@
<?php
$_tests_dir = getenv('WP_TESTS_DIR');
if ( !$_tests_dir ) $_tests_dir = '/tmp/wordpress-tests-lib';
require_once $_tests_dir . '/includes/functions.php';
function _manually_load_plugin() {
$plugins_dir = dirname( __FILE__ ).'/../../../plugins';
$timber = $plugins_dir.'/timber/timber.php';
if ( file_exists($timber) ) {
require_once($timber);
} else {
$timber_library = $plugins_dir.'/timber-library/timber.php';
if ( file_exists($timber_library) ) {
require_once($timber_library);
}
}
}
tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
require $_tests_dir . '/includes/bootstrap.php';

View File

@ -0,0 +1,55 @@
<?php
class TestTimberStarterTheme extends WP_UnitTestCase {
function setUp() {
self::_setupStarterTheme();
switch_theme( basename( dirname( dirname( __FILE__ ) ) ) );
require_once(__DIR__.'/../functions.php');
}
function tearDown() {
switch_theme('twentythirteen');
}
function testTimberExists() {
$context = Timber::context();
$this->assertTrue(is_array($context));
}
function testFunctionsPHP() {
$context = Timber::context();
$this->assertEquals('StarterSite', get_class($context['site']));
$this->assertTrue(current_theme_supports('post-thumbnails'));
$this->assertEquals('bar', $context['foo']);
}
function testLoading() {
$str = Timber::compile('tease.twig');
$this->assertStringStartsWith('<article class="tease tease-" id="tease-">', $str);
$this->assertStringEndsWith('</article>', $str);
}
/**
* Helper test to output current twig version
*/
function testTwigVersion() {
$str = Timber::compile_string("{{ constant('Twig_Environment::VERSION') }}");
//error_log('Twig version = '.$str);
}
function testTwigFilter() {
$str = Timber::compile_string('{{ "foo" | myfoo }}');
$this->assertEquals('foo bar!', $str);
}
static function _setupStarterTheme(){
$dest = WP_CONTENT_DIR . '/themes/' . basename( dirname( dirname( __FILE__ ) ) );
$src = realpath( __DIR__ . '/../../' . basename( dirname( dirname( __FILE__ ) ) ) );
if ( is_dir($src) && !file_exists($dest) ) {
symlink($src, $dest);
}
}
}

0
web/app/uploads/.gitkeep Normal file
View File

6
web/index.php Normal file
View File

@ -0,0 +1,6 @@
<?php
/**
* WordPress View Bootstrapper
*/
define('WP_USE_THEMES', true);
require __DIR__ . '/wp/wp-blog-header.php';

9
web/wp-config.php Normal file
View File

@ -0,0 +1,9 @@
<?php
/**
* Do not edit this file. Edit the config files found in the config/ dir instead.
* This file is required in the root directory so WordPress can find it.
* WP is hardcoded to look in its own directory or one directory up for wp-config.php.
*/
require_once dirname(__DIR__) . '/vendor/autoload.php';
require_once dirname(__DIR__) . '/config/application.php';
require_once ABSPATH . 'wp-settings.php';

3
wp-cli.yml Normal file
View File

@ -0,0 +1,3 @@
path: web/wp
server:
docroot: web