Skip to content

CityOfNewYork/working-nyc

Repository files navigation

Working NYC

Image of a person using the Working NYC website with their phone.

Working NYC helps New Yorkers connect to the services and resources they need to find a new or better job. The site accommodates NYC residents...

  • With low digital literacy
  • With limited technology access, especially those who are mobile dependent
  • Who do not speak fluent English
  • Who have limited visual capabilities

Learn more about Working NYC at nyc.gov/opportunity.

Tech

Working NYC is a publicly available WordPress site hosted on WP Engine. Source code is available in this repository. The Opportunity Standard provides mobile-first stylesheets, fonts, icons, and JavaScript-enhanced components that support WCAG AA compliance, and multi-lingual (right-to-left, and left-to-right) layouts. They are distributed as an NPM Package which can be installed in any project.

Local Installation

Requirements

Installation

This guide covers running the WordPress site without a specific virtualization method. The NYCO WordPress Boilerplate is used by the team to manage WordPress sites locally.

$1 Rename wp-config-sample.php to wp-config.php. Modify the MySQL settings, Authentication Unique Keys, Salts, and WordPress debugging mode. If using the NYCO WordPress Boilerplate, you can use the wp-config.php included in the repository but you should still update the salts.

$2 To get un-tracked composer packages when you install the site you will need to run the following in the root of the WordPress site where the composer.json file lives:

composer install

$3 This will install plugins included in the Composer package, including NYCO WordPress Config (see details in Configuration below). This plugin includes a sample config that needs to be renamed from mu-plugins/config/config-sample.yml to mu-plugins/config/config.yml.

WordPress Site Structure

Configuration

Working NYC integrates the NYCO WordPress Config plugin for determining configurations based on the environment. This plugin will pull from an array of variables set in the mu-plugins/config/config.yml file and set the appropriate group to environment variables that can be accessed by site functions, templates, and plugins.

Theme

The theme for the site contains all of the documentation, PHP functions, templates, styling, and scripts for the site front-end and can be found in the themes directory.

Plugins

WordPress Plugins are managed via Composer and the WordPress Admin. They are tracked by the repository to be easily shipped to different environments. Plugins utilized by the WordPress site can be found in the plugins directory. Key plugins include Advanced Custom Fields Pro, WordPress Multilingual, and the Gather Content WordPress Integration. There are a few ways of managing plugins.

WordPress Admin Plugins

Not all plugins can be managed by Composer. Specifically Advanced Custom Fields Pro and WordPress Multilingual. These plugins must be updated by either downloading from their respective sites and adding directly to the wp-content/plugins directory or by logging into the WordPress Admin and updating via the /wp-admin/plugins page.

Must Use Plugins

Must Use Plugins are used to handle most of the custom configuration for the WordPress site including custom post types, plugin configuration, and special plugins that enable additional functionality for major features of the site. Those can be found in the mu-plugins directory.

Composer Plugins

The composer.json file illustrates which plugins can be managed by Composer. WordPress Plugins can be installed either from WordPress Packagist or from Packagist via the Composer Libray Installer. Other PHP packages that are not plugins and stored in the /vendor directory are tracked by git so they can be deployed with the code. See the .gitignore file under the "Composer" block.

Using Composer

Installer Paths

Composer will install packages in one of three directory locations on 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 that have the Composer Library Installer included as a dependency can 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), however, for 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 into 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 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   # etc.
...

Autoloader

The autoloader is what includes PHP package files in the application. It works by requiring package PHP files when the class names they include are invoked. The autoloader needs to be required in every application before Composer packages can be run. The site requires the autoloader in 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

require_once ABSPATH . '/vendor/autoload.php';

Development build

Different types of autoloaders can be generated. The composer.json includes scripts that will generate a "development" autoloader that requires packages defined in the require and require-dev json blocks (including whoops).

composer run development

Production build

The "production" autoloader will only require packages in the require JSON block. Once you are done developing and before deployment, regenerate the production autoloader which will prevent development dependencies from being required.

composer run production

Requiring Packages

The command to install new packages is composer require. See the Composer docs for more details on the CLI. Packages can be installed from Packagist or WordPress Packagist. To require a package run:

composer require {{ vendor }}/{{ package }}:{{ version constraint }}

For example:

composer require timber/timber:^1.18

... will require the Timber package and install the latest minor version, greater than 1.18 and less than 2.0.0. The caret designates the version range. Version constraints can be read about in more detail in the Composer documentation.

Updating Packages

The command to update packages is composer update. Running it will install packages based on their version constraint in the composer.json file. Individual packages can be updated by specifying the package name.

composer update {{ vendor }}/{{ package }}

For example:

composer update timber/timber

Composer scripts

The Composer package includes scripts that can be run via the command:

composer run {{ script }}
Script Description
development Rebuilds the autoloader including development dependencies.
production Rebuilds the autoloader omitting development dependencies.
predeploy Rebuilds the autoloader using the production script then runs PHP Code Sniffer using the lint script (described below).
lint Runs PHP Code Sniffer which will display violations of the standard defined in the phpcs.xml file.
fix Runs PHP Code Sniffer in fix mode which will attempt to fix violations automatically. It is not necessarily recommended to run this on large scripts because if it fails it will leave a script partially formatted and malformed.
version Regenerates the composer.lock file and rebuilds the autoloader for production.
deps This is a shorthand for composer show --tree for illustrating package dependencies.

Git Hooks

Before contributing, configure git hooks to use the repository's hooks.

git config core.hooksPath .githooks
Hook Description
pre-push Runs the Composer predeploy script. See composer scripts.

Coding Style

PHP

PHP is linted using PHP Code Sniffer with the PSR-2 standard. The configuration can be found in the phpcs.xml. Linting must be done manually using the command:

composer run lint

PHP Code Sniffer can attempt to fix violations. Run the following command in a clean git directory. Occasionally, with multiple files and large scripts it can fail and leave malformed PHP files.

composer run fix

Security

The team @NYCOpportunity actively maintains and releases updates to the site to ensure security using a combination of practices for WordPress. The NYCO WordPress Boilerplate README file documents some of these tools and best practices.

Reporting a Vulnerability

Please report any vulnerabilities confidentially using the GitHub Security Advisories Feature.


The Mayor's Office for Economic Opportunity Civic Tech

Working NYC is maintained by the New York City Mayor's Office for Economic Opportunity (NYC Opportunity). We are committed to sharing open source software that we use in our products. Feel free to ask questions and share feedback. Follow @nycopportunity on Github, Twitter, Facebook, and Instagram.