Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/cityofnewyork/nyco-wp-boilerplate

Local development suite for creating and running instances of WordPress sites and managing them on WP Engine. Maintained by @NYCOpportunity
https://github.com/cityofnewyork/nyco-wp-boilerplate

composer docker nyc-opportunity nycopportunity security wordpress wp-cli wp-engine wpengine

Last synced: about 1 month ago
JSON representation

Local development suite for creating and running instances of WordPress sites and managing them on WP Engine. Maintained by @NYCOpportunity

Awesome Lists containing this project

README

        

# NYCO WordPress Boilerplate

At NYC Opportunity, we are utilizing Docker to help us more easily and consistently manage our products, specifically, [ACCESS NYC](https://github.com/CityOfNewYork/ACCESS-NYC), [Growing Up NYC](https://github.com/CityOfNewYork/growingupnyc), [Working NYC](https://github.com/CityOfNewYork/working-nyc), and more.

This repository contains a Docker image that will install the latest version of WordPress to be served by nginx. It is the Boilerplate for running and maintaining all of our WordPress products and contains scripts for deployment, syncing, configuration, and notifications with all product environments hosted on WP Engine.

## Docker Images

- [nginx](https://hub.docker.com/_/nginx/) Alpine
- [WordPress](https://hub.docker.com/_/wordpress) PHP FPM Alpine
- [MySQL](https://hub.docker.com/_/mysql)

### Optional Images

- [redis](https://hub.docker.com/_/redis)
- [phpMyAdmin](https://hub.docker.com/r/phpmyadmin/phpmyadmin/)

## Usage

Below is simplified set of steps for getting started. Look at the [notes for special details](#notes).

**$1** Download a zip of this repository, or clone it to a new project directory.

```shell
git clone https://github.com/CityOfNewYork/nyco-wp-boilerplate.git your-project-name && cd your-project-name
```

**$2** Run the `bin/boilerplate` command, select `[2] Update your Wordpress Project` then `[1] Yes` in the prompt to proceed. This will hide the `.git` directory but save it for updating later (see [Dual Project Development](#dual-project-development) for more details).

**$3** Move your files into the **[/wp](wp/)** starter directory. *Optionally*, clone or place a WordPress site in the current directory (if doing this see the [**/wp directory** note](#notes) below).

**$4** *Optional* but important if you have a database dump to work with. Place any **.sql** file in the [**/data**](data/) directory. See [notes below for details on seeding the database](#notes).

**$5** Run

```shell
docker-compose build
```

to build your images. Then run

```shell
docker-compose up
```

to start them. After a few moments, you will be able to open up `localhost:8080` to visit your site.

### Notes

* **Generate your [Salts](https://api.wordpress.org/secret-key/1.1/salt/)** then copy and paste them in their corresponding fields in the [wp-config.php](wp/wp-config.php) file.

* **Mounting files**: The Docker image will pull the latest version of WordPress and mount any files to the WordPress container not included in the **[/wp](wp/)** when running `docker-compose build` so you could have only the **/wp-content** directory in your project if you always want to work with the latest version of WordPress. The [**docker-compose.yml**](docker-compose.yml) file includes commented out lines that will also achieve the same thing for mounting certain files to the WordPress container.

* **Bootstrapping**: In the [**/wp**](wp/) directory provided you'll find sample [**composer.json**](wp/composer.json), [**phpcs.xml**](wp/phpcs.xml), [**.gitignore**](wp/.gitignore), [**wp-config.php**](wp/wp-config.php) files to help bootstrap a new WordPress project. You may delete, replace, or modify any boilerplate files in the [**/wp**](wp/) directory to meet your project's needs.

* **/wp directory**: You can clone a WordPress site directly into the boilerplate root and delete the [**/wp**](wp/) directory. You will need to update the [**/config/bin.cfg**](config/bin.cfg) `WP` setting and the instances of **./wp** in the [**docker-compose.yml**](docker-compose.yml) file.

* **Database Seeding**: The name for the **.sql** dump does not matter as the mysql image will look for any **.sql** file in the [**/data**](data/) directory and execute it on the database defined in the [**docker-compose.yml**](docker-compose.yml) file. You will need to 'Find and Replace' the site url value in the **.sql** file to match your expected host (the default expected host is `http://localhost:8080`). This can be done manually before import in any text editing program or after using the [WP-CLI](#wp-cli). If there is no SQL file present when the image is created it will create an empty database which you can import data into using the [WP-CLI](#wp-cli), [Sequel Pro](https://www.sequelpro.com/), or *phpMyAdmin*.

* **Database Reset**: To reset the database you can remove the service container `docker-compose rm mysql`, then, remove the volume `docker volume rm {{ volume name }}`. To look up the volume name use `docker volume ls`.

* **Proxy**: If you are working behind a proxy, uncomment associated lines in the main [**wordpress-fpm/Dockerfile**](wordpress-fpm/Dockerfile) and enter your proxy in the appropriate areas.

* **WP Engine Sites**: If copying an existing WP Engine WordPress site from a backup point, it will have it's own **/wp-config.php** file and some "drop in" plugins in the **/wp-content** directory and "must use" **wp-content/must-use** directory included.

* **Composer**: If running `composer install` fails and you have a **composer.phar** file in your root directory, run `php composer.phar i`. If you do not have Composer installed, see [Get Composer](https://getcomposer.org/).

* **Optional Images**: To use optional images, uncomment them in the [**docker-compose.yml**](docker-compose.yml) file.

* **Docker**: You can use the `-d` flag (`docker-compose up -d`) to run in detached mode.

* **Docker**: To create an interactive shell with the WordPress container, you can run `docker-compose exec wordpress sh`.

## Configuration

The [Bin Scripts](#bin-scripts) use a configuration file in [**/config/bin.cfg**](config/bin.cfg) for interacting with the local WordPress site and remote services.

Config Blocks | Description
-------------------|-
Colors | These are the colors used for Slack and other message highlighting. They currently are set to match the NYC Opportunity brand. Used by the [push](#push) command.
Domain | The production domain and CDN for the WP Engine installation go here. Used by the [sourcemaps](#sourcemaps) command.
WordPress | WordPress directory configuration including the `WP` path, theme directory name, minified *.js* directory path, and matching pattern for minified *.js* files. Used by [sourcemaps](#sourcemaps) and other [commands](#commands).
GitHub | `GITHUB_URL` The url for the product repository. Used by the [push](#push) command.
Projects | All of the product environment remote names should be added here. Used by the [menu](#menu) command.
Rollbar | The access token for the a [Rollbar](https://rollbar.com) account and local Rollbar username go here. Used by the [push](#push) and [sourcemaps](#sourcemaps) commands.
Slack | Deployment and synchronization scripts post to Slack to alert the team on various tasks. Used by various [commands](#commands).
S3 Uploads | The name of an S3 bucket where uploads may be stored. Only needed if using the [uploads](#uploads) command.
WP Engine API | Commands that use the [WP Engine API](https://wpengineapi.com/) require API credentials to be [generated in your user profile](https://my.wpengine.com/api_access) and set to the variables in this block.

### NYCO WP Config

[**config/config.yml**](config/config.yml) - This file is used in conjunction with the [NYCO WP Config](https://github.com/cityofnewyork/nyco-wp-config) WordPress plugin for environment configuration. [See that repository](https://github.com/cityofnewyork/nyco-wp-config) for details on integrating with WordPress. If a site uses that plugin it needs to be present in the **wp-content/mu-plugins/config/** directory.

## WP-CLI

WP-CLI is a command line interface for WordPress. It is set up to work with your WordPress installation through this Boilerplate. [Read more about WP-CLI at it's website](https://wp-cli.org/). To use WP-CLI commands, you need to run...

```shell
docker-compose exec wordpress /bin/wp {{ command }}
```

... in place of `wp {{ command }}` to run one off commands on the container. Optionally, create an alias...

```shell
alias dcwp="docker-compose exec wordpress /bin/wp"
```

... so you don't have to type out `docker-compose exec`. **Optionally**, shell into the container to run commands directly in the container.

```shell
docker-compose exec wordpress sh
```

Then commands can be run using the normal CLI;

```shell
wp {{ command }}
```

### Uses

There a lot of things you can do with the CLI such as import a database...

```shell
wp db import database.sql
```

... replace strings in a the database...

```shell
wp search-replace 'https://production.com' 'http://localhost:8080'
```

... and add a local administrative user:

```shell
wp user create username [email protected] --role=administrator --user_pass=wp
```

[Refer to the documentation for more commands](https://developer.wordpress.org/cli/commands/).

## Composer

This boilerplate comes with a root composer package that you may use to manage php packages and plugins. To use composer, [install it](https://getcomposer.org/) on your machine and run...

```shell
composer update
```

... to install the vendor package (or `php composer.phar i` depending on your setup). You may also want to add **/vendor** to your WordPress **.gitignore** file, if it hasn't been already.

### Required Plugins and Packages

The root Composer package requires the following packages and plugins. Plugins for enhancing WordPress security are denoted by `*`. These enhance some of the security measures provided by WordPress and WP Engine, however, using plugins alone is not a comprehensive solution for securing WordPress websites. Refer to the [security section](#security) for more details.

Composer Packages | Type | Description
--------------------------------------------------------------------------------------------------------------------|---------------------------|-
[Duplicate Post](https://wordpress.org/plugins/duplicate-post/) | Plugin | Enables the duplication of posts and custom post types.
[NYCO WP Config](https://packagist.org/packages/nyco/wp-config) | Must Use Plugin | Determines php constants set on runtime based on specific environments. The plugin will pull from an object of variables set in the [mu-plugins/config/config.yml](wp/wp-content/mu-plugins/config/config.yml) file and set the appropriate group to constants that can be accessed by site functions, templates, and plugins. It will also autoload an environment-specific php file from the [mu-plugins/config/](wp/wp-content/mu-plugins/config/).

To pull in the appropriate settings, set the `WP_ENV` constant in the **wp-config.php** file of each environment. For example; `define('WP_ENV', 'development');` will load the default secrets at the root level of the **config.yml** file and the `development:` block as well as autoload the [**development.php**](wp/wp-content/mu-plugins/config/development.php) file.

Default constants are loaded in the root of the config.yml file and the [**default.php**](wp/wp-content/mu-plugins/config/default.php) configuration file is always loaded (the [Composer autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading) is required here).
[NYCO WP Assets](https://packagist.org/packages/nyco/wp-assets) | Must Use Plugin | Provides helper functions for enqueuing JavaScript and stylesheet assets and integrations defined in the [mu-plugins/config/integrations.yml](wp/wp-content/mu-plugins/config/integrations.yml) file.
[S3 Uploads](https://github.com/humanmade/S3-Uploads) | Plugin | A lightweight plugin for storing uploads on Amazon S3 instead of the local filesystem. Note, this requires an [AWS S3 bucket](https://aws.amazon.com/s3/).
[Timber](https://www.upstatement.com/timber/) | Vendor | Integrates the Twig Template Engine and more for easier theme development.
* [Aryo Activity Log](https://wordpress.org/plugins/aryo-activity-log/) | Plugin | * Tracks and displays user activity in a dedicated log page.
* [Google Authenticator](https://wordpress.org/plugins/google-authenticator/) | Plugin | * Enables 2-Factor Authentication for WordPress Users.
* [Limit Login Attempts Reloaded](https://wordpress.org/plugins/limit-login-attempts-reloaded/) | Plugin | * Limits the number of login attempts a user can have if they use the wrong password or authenticator token.
* [LoggedIn](https://wordpress.org/plugins/loggedin/) | Plugin | * Allows the setting for number of active logins a user can have.
* [WP Security Questions](https://wordpress.org/plugins/wp-security-questions/) | Plugin | * Enables security question feature on registration, login, and forgot password screens.
* [WPS Hide Login](https://wordpress.org/plugins/wps-hide-login/) | Plugin | * Lets site administrators customize the url of the WordPress admin login screen.
* [WPScan](https://wordpress.org/plugins/wpscan/) | Plugin | * Identifies security issues of WordPress plugins installed against the [WPScan Vulnerability Database](https://wpvulndb.com/).
* [Defender](https://wordpress.org/plugins/defender-security) | Plugin | * Provides a selection of security measures such as hiding the default **/wp-login.php** path for logging into the cms, enabling two-factor authentication, setting security headers, and more. This plugin provides a good all-in-one solution and UI for modifying security features for site administrators, however, most of the features it provides can be hard-coded with plugins described above and [Must Use Plugins](#must-use-plugins).
**Require Dev** | | The following packages are included for local development and purposes in the `require-dev` block.
[Code Sniffer](https://github.com/squizlabs/PHP_CodeSniffer) | Vendor | Code linting for PHP.
[Whoops](https://github.com/filp/whoops) | Vendor | Much nicer error log for PHP.
[Query Monitor](https://wordpress.org/plugins/query-monitor/) | Plugin | Creates a developer tools panel for WordPress Admins.
[Redis Cache](https://wordpress.org/plugins/redis-cache/) | Plugin | A persistent object cache powered by Redis. Using Object Caching is optional but it is recommended for site speed.
[WordPress Auto Login](https://wordpress.org/plugins/wp-auto-login/) | Plugin | Creates a quick login link for local development. **Important**, this is ignored by the site's **.gitignore** so it doesn't get added to a live environment.
[WP Crontrol](https://wordpress.org/plugins/wp-crontrol/) | Plugin | Lets you view and control what’s happening in the WP-Cron system.

### Using Composer

* [Installer Paths](#installer-paths)
* [/vendor and git](#vendor-and-git)
* [Autoloader](#autoloader)
* [Requiring Packages](#requiring-packages)
* [Updating packages](#updating-packages)
* [Composer scripts](#composer-scripts)

#### Installer Paths

Composer will install packages in one of three directory locations in the site depending on the type of package it is.

* **/vendor**; by default, Composer will install packages here. These may include helper libraries or SDKs used for php programming.

Packages have the [Composer Library Installer](https://github.com/composer/installers) included as a dependency are able to reroute their installation to directories alternative to the **./vendor** directory. This is to support different php based application frameworks. For WordPress, there are four possible directories ([see the Composer Library Installer documentation for details](https://github.com/composer/installers#current-supported-package-types)), however, for the purposes of this site most packages are installed the two following directories:

* **/wp-content/plugins**; packages that are WordPress plugins are installed in the WordPress plugin directory.
* **/wp-content/mu-plugins**; packages that are Must Use WordPress plugins are installed in the Must Use plugin directory.

#### /vendor and git

Normally, **/vendor** packages wouldn't be checked in to version control. They are installed on the server level in each environment. However, this site is deployed to WP Engine which does not support Composer so the packages need to be checked in and deployed to the site using git. By default **/vendor** packages are not tracked by the repository. If a composer package is required by production it needs to be included in the repository so it can be deployed to WP Engine. The [**.gitignore**](.gitignore) manually includes tracked repositories using the `!` prefix. This does not apply to WordPress plugins.

```
# Composer #
############
/vendor/* # Exclude all /vendor packages
!/vendor/autoload.php # Include the autoloader
!/vendor/altorouter # example package inclusion
...
```

#### Autoloader

The [autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading) is what includes PHP package files in the application. It works by requiring package php files when the classnames they include are invoked. The autoloader needs to be required in every application before Composer packages can be run. The site loads requires the autoloader in [/wp-content/mu-plugins/config/default.php](wp-content/mu-plugins/config/default.php). This only applies to packages in the **/vendor** directory. WordPress Plugins and Must Use Plugins are not autoloaded.

```php


├ 📁 .githooks - Hooks to run when committing, pushing, etc. This directory needs to be configured in the repo configuration by running; git config core.hooksPath .githooks
└ 📄 pre-push - Runs the Composer predeploy script before pushing to the remote repository.
├ 📁 .github - GitHub configurations.
└ 📄 dependabot.yml - Dependabot configuration.
├ 📁 vendor - Composer packages will be installed here.
├ 📁 wp-admin - WordPress Core directory.
├ 📁 wp-content - Must use plugins, themes, uploads, etc.
├ 📁 wp-includes - WordPress Core directory.
├ 📄 .gitignore - Git file ignores and includes.
├ 📄 composer.json - Root composer package containing required packages, plugins, and Composer scripts. See composer.json schema docs and Composer guide.
├ 📄 composer.lock - Composer lock package that defines the required versions.
├ 📄 phpcs.xml - NYCO PHP Code Sniffer configuration. PSR2 with two spaces, braces on same line.
├ 📄 README.md - Site readme file.
├ 📄 SECURITY.md - Site security policy.
├ 📄 LICENSE - Site open source license.
├ 📄 wp-config.php - Database, salts, debug settings. Note, this should not be checked into a project's repository. The 📄 wp-config.php file in the local project will differ from the one in a remote environment.
└ 📄 ...

## Must Use Plugins


- 📂 wp-content
├ 📂 mu-plugins
├ 📁 ...
└ 📄 ...
├ 📁 ...
└ 📄 ...

[Must Use Plugins](https://codex.wordpress.org/Must_Use_Plugins) can be used to handle most of the custom configuration for the WordPress site including [registering custom post types](https://developer.wordpress.org/plugins/post-types/registering-custom-post-types), [registering WordPress REST API routes](https://developer.wordpress.org/rest-api/extending-the-rest-api/routes-and-endpoints/), configuring plugin settings, and other functionality for major features of the site. Most WordPress code bases tend to keep these in the [theme](#theme) which is better suited for styling the front-end and passing context to view templates.

* Custom Post Type Registration
* WordPress REST API Route Registration
* Constant Definition (using the [NYCO WordPress Config plugin](https://github.com/cityofnewyork/nyco-wp-config) or other). Note, some constants need to be defined in the root 📄 **wp-config.php** file.
* Integration Configuration such as Google Analytics, Tag Manager (event tracking), and Optimize (A/B testing). The [NYCO WordPress Assets plugin](https://github.com/cityofnewyork/nyco-wp-assets) can manage the configuration of integrations.
* Plugin Configuration
* Additional Logic and Custom Functionality

This repository includes some [Must Use Plugins](wp/wp-content/mu-plugins/) to provide support for security concerns (denoted by `*`) and plugin/site configuration. They can be customized for any installation.

Plugin | Description
--------------------------------------------------------------------------------------------------------------------|-
[@config](wp/wp-content/mu-plugins/@config.php) | Instantiates [NYCO WP Config](https://packagist.org/packages/nyco/wp-config). The `@` symbol in the file name ensures this plugin is instantiated before everything else as it contains constant settings that may be relevant to other plugins.
[Add meta description to head](wp/wp-content/mu-plugins/add-meta-description-to-head.php) | Adds the description defined in the WordPress Admin settings to the description meta tag in the head for the homepage only.
[Clean up head](wp/wp-content/mu-plugins/clean-up-head.php) | Remove unnecessary scripts, styles, and tags from the default WordPress head tag.
[Robots.txt](wp/wp-content/mu-plugins/robots-txt.php) | Modifies the default output of WordPress' robots.txt based on the WordPress Search Engine Visibility Settings (Settings > Reading).
[Timber](wp/wp-content/mu-plugins/timber.php) | Instantiates [Timber](https://timber.github.io/docs/getting-started/setup/#via-github-for-developers) for a more pleasant theme development experience.
[Upload Mimes](wp/wp-content/mu-plugins/upload-mimes.php) | Adds the SVG mime type to enable support for SVG files in the media uploader.
[WP Assets](wp/wp-content/mu-plugins/wp-assets.php) | Instantiates [NYCO WP Assets](https://packagist.org/packages/nyco/wp-assets).
[WP Assets Integrations](wp/wp-content/mu-plugins/wp-assets-integrations.php) | Add an Advanced Custom Fields option page for toggling NYCO WordPress Assets integrations.
* [Auto update options](wp/wp-content/mu-plugins/auto-update-options.php) | * Disables ping-back flag, pings, comments, closes comments for old posts, notifies if there are new comments, and disables user registration.
* [Close attachment comments and pings](wp/wp-content/mu-plugins/close-attachment-comments.php) | * Disable future comments and ping status (spam) for attachments as there is no way to close comments in admin settings. For previously uploaded attachments the wp cli can be used to close them (examples are included in the source of this plugin).
* [Configure core sitemaps](wp/wp-content/mu-plugins/core-sitemaps.php) | * Configuration for the [WordPress sitemaps feature](https://make.wordpress.org/core/2020/07/22/new-xml-sitemaps-functionality-in-wordpress-5-5/). Filters out users, taxonomies, and other post types that do not have page views. Note, prior to WordPress 5.5 this was not available to WordPress natively.
* [Disable XML-RPC](wp/wp-content/mu-plugins/disable-xmlrpc.php) | * [Disable XML-RPC methods](https://kinsta.com/blog/wordpress-xml-rpc/) that require authentication.
* [Nonce Life](wp/wp-content/mu-plugins/nonce-life.php) | * Changing the default [WordPress nonce lifetime](https://codex.wordpress.org/WordPress_Nonces#Modifying_the_nonce_system) from 1 day to 30 minutes.
* [REST Endpoints](wp/wp-content/mu-plugins/rest-endpoints.php) | * Explicitly disables [WordPress REST API user endpoints](https://developer.wordpress.org/rest-api/reference/users/).
* [WP Headers](wp/wp-content/mu-plugins/wp-headers.php) | * This plugin enables sending security headers to the client. The headers are configured by defining php [constants described below](#wp-header-constants).

### WP Header Constants

Configuration for the WP Headers Must Use Plugin included in this repository.

Constant | Type | Default Value | Description
----------------------------------|-----------|-----------------------------------------|-
`WP_HEADERS_DNS_PREFETCH_CONTROL` | *string* | `undefined` | Set to `'on'` for [`X-DNS-Prefetch-Control`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control).
`WP_HEADERS_SAMEORIGIN` | *boolean* | `undefined` | `true` sets [`X-Frame-Options`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) to `SAMEORIGIN`.
`WP_HEADERS_NOSNIFF` | *boolean* | `undefined` | `true` sets [`X-Content-Type-Options`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options) to `nosniff`.
**CSP Header Policy Constants** | | | [Content Security Policies](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). Each of the constants below build up into the single custom content security policy.
`WP_HEADERS_CSP_DEFAULT` | *string* | `'self'` | [Default directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src) for unspecified policies.
`WP_HEADERS_CSP_STYLE` | *string* | `'self'` | [Stylesheet source directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src).
`WP_HEADERS_CSP_FONT` | *string* | `'self'` | [Font source directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/font-src).
`WP_HEADERS_CSP_IMG` | *string* | `'self'` | [Image source directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/img-src).
`WP_HEADERS_CSP_SCRIPT` | *string* | `'self' 'nonce-{{ CSP_SCRIPT_NONCE }}'` | [JavaScript source directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src). A nonce will be created and a `script_loader_tag` filter will append the nonce to scripts that are registered and enqueued. The nonce will also be set to the constant `CSP_SCRIPT_NONCE` that can be added to permit inline `` tags in templates.
`WP_HEADERS_CSP_CONNECT` | *string* | `'self'` | [JavaScript URL loading directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/connect-src).
`WP_HEADERS_CSP_FRAME` | *string* | `'none'` | [iFrame source directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-src).
`WP_HEADERS_CSP_OBJECT` | *string* | `'none'` | [Object, embed, and applet directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/object-src).
`WP_HEADERS_CSP_REPORTING` | *string* | `undefined` | Sets the [reporting directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-to) to an endpoint for debugging the policy and violations. Sets both the `report-to` and `report-uri` for compatibility. Note, the endpoint that processes the response needs to be created.
`WP_HEADERS_CSP_SEND` | *boolean* | `undefined` | Setting `false` will prevent the CSP header policy from being sent.

## Theme

<div><pre>
- 📂 wp-content
├ 📂 themes
└ 📂 theme
├ 📁 ...
└ 📄 ...
├ 📁 ...
└ 📄 ...
</div></pre>

The theme for the site contains all of the php functions, templates, styling, and scripts relevant the front-end templates. This is the only WordPress theme that is compatible with the WordPress site.

* View Controllers
* View Templates
* View Assets and Source
* Gutenberg Blocks
* Shortcodes
* Template functions and tags

<div><pre>
├ 📁 acf-json - <a href="https://www.advancedcustomfields.com/resources/local-json/">Advanced Custom Fields JSON</a> files for syncing custom fields between environments.
├ 📁 assets - The source for image, style, and script files live in the 📂 src directory and are compiled to the 📂 assets directory. This is done with NPM Scripts in 📄 package.json file and 📁 node_scripts directory.
├ 📁 blocks - Custom <a href="https://developer.wordpress.org/block-editor/developers/">Gutenberg Block</a> source.
├ 📁 lib - Theme functions, filters, and other helpers that assist in rendering views (includes).
├ 📁 node_modules - Node modules will be installed here if using NPM to manage dependencies.
├ 📁 node_scripts - Custom node scripts required to manage assets.
├ 📁 shortcodes - Theme <a href="https://codex.wordpress.org/Shortcode">shortcodes</a> available to content administrators.
├ 📁 timber-posts - Site and Post Type classes that <a href="https://timber.github.io/docs/guides/extending-timber/">extend Timber posts</a> and provide processed data to views.
├ 📄 Site.php - Timber site class extension to add properties to <a href="https://timber.github.io/docs/reference/timber-site/">Timber/Site</a>.
├ 📄 Post.php - Timber post class extension.
└ 📄 ...
├ 📂 src - Asset source.
├ 📁 scss - Sass source, if required.
├ 📄 _main.scss - Main Sass entry-point.
├ 📄 ar.scss - Arabic font variable setting.
├ 📄 light.scss - Light color mode variable setting.
├ 📄 dark.scss - Dark color mode variable setting.
├ 📄 latin.scss - Latin font face variable setting.
├ 📄 ltr.scss - Left-to-right variable setting.
├ 📄 rtl.scss - Right-to-left variable setting.
├ 📄 ko.scss - Korean font face variable setting.
├ 📄 ur.scss - Urdu font face variable setting.
├ 📄 zh-hant.scss - Chinese font face variable setting.
└ 📄 ...
└ 📁 js - JavaScript source.
├ 📁 modules - Supporting ES modules.
├ 📄 main.js - Main JavaScript entry-point.
├ 📄 search.js - The Search view JavaScript (if required).
├ 📄 single.js - The Single view JavaScript (if required).
└ 📄 ...
├ 📂 views - View templates are generally organized on a component level and by site feature, including <a href="https://twig.symfony.com/">Twig</a>, <a href="https://vuejs.org/v2/guide/single-file-components.html">Vue.js</a>, <a href="https://reactjs.org/docs/introducing-jsx.html">JSX</a>, and/or jst (pre-compiled js templates) files.
├ 📁 components - Component pattern templates.
├ 📁 elements - Element pattern templates.
├ 📁 emails - Email view templates (if required).
├ 📁 objects - Object pattern templates.
├ 📁 partials - Misc. view template partials.
├ 📄 base.twig - The base template, extended by view templates.
├ 📄 search.twig - The search view template.
├ 📄 singular.twig - The single view template.
└ 📄 ...
├ 📄 archive.php - Archive view controller. Context for the view is added here.
├ 📄 footer.php - This may be required to prevent plugins from using the wp_footer() function to render output.
├ 📄 functions.php - Main PHP entry point. Includes files from 📁 blocks, 📁 lib, and 📁 shortcodes.
├ 📄 header.php - This may be required to prevent plugins from using the wp_header() function to render output.
├ 📄 index.php - Index view controller. Context for the view is added here.
├ 📄 search.php - Search view controller. Context for the view is added here.
├ 📄 singular.php - Single view controller. Context for the view is added here.
├ 📄 .nvmrc - If a specific node version is required, this file can specify the version. More details can be found in the <a href="https://github.com/nvm-sh/nvm#nvmrc">Node Version Manager docs</a>.
├ 📄 package.json - Contains required front-end packages for the theme.
├ 📄 package-lock.json - Keep the package lock file along with the theme.
├ 📄 manifest.json - A <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a> file for progressive web applications.
├ 📄 style.css - Theme meta data; name, version, author, etc.
├ 📄 editor-style.css - Editor styles. <a href="https://developer.wordpress.org/block-editor/developers/themes/theme-support/#editor-styles">Theme support needs to be added and the stylesheet must be instantiated</a>.
├ 📄 wp-admin-bar.css - WP Admin Bar styles (if any). This stylesheet needs to be registered and enqueued for admin views.
└ 📄 ...
</pre></div>

<!-- # Environments

TEST
STAGING
PRODUCTION -->

# Security

Refer to this [free security whitepaper](https://wordpress.org/about/security/) from WordPress.org to become more familiar with the security components and best practices of the WordPress Core software. Additionally, the [Open Web Application Security Project](https://www.owasp.org/index.php/About_The_Open_Web_Application_Security_Project) (OWASP) provides [guidelines for implementing security for WordPress sites](https://www.owasp.org/index.php/OWASP_Wordpress_Security_Implementation_Guideline) that includes free and open source resources instead of commercial ones. Some of the practices mentioned are included in this boilerplate through plugins and documentation while others should be implemented on a case by case basis.

---

![The Mayor's Office for Economic Opportunity](NYCMOEO_SecondaryBlue256px.png)

[The Mayor's Office for Economic Opportunity](http://nyc.gov/opportunity) (NYC Opportunity) is committed to sharing open source software that we use in our products. Feel free to ask questions and share feedback. **Interested in contributing?** See our open positions on [buildwithnyc.github.io](http://buildwithnyc.github.io/). Follow our team on [Github](https://github.com/orgs/CityOfNewYork/teams/nycopportunity) (if you are part of the [@cityofnewyork](https://github.com/CityOfNewYork/) organization) or [browse our work on Github](https://github.com/search?q=nycopportunity).