├── documentation
├── troubleshooting
│ ├── gulp4.md
│ └── css-grid.md
├── recommended-extensions.md
├── PHPCS.md
├── BrowserSync.md
├── Advanced-Features-(and-how-to-use-them).md
├── git-workflow.md
├── gulp.md
├── css.md
└── php.md
├── README.md
├── CODE_OF_CONDUCT.md
├── GOVERNANCE.md
└── LICENSE
/documentation/troubleshooting/gulp4.md:
--------------------------------------------------------------------------------
1 | # Updating to Gulp 4
2 |
3 | Gulp 4 uses an updated CLI (Command Line Interface). If the computer you are using already has Gulp installed, there is a good chance you have an older version of the CLI and you will encounter errors when trying to run WP Rig.
4 | ## Updating the Gulp 4 CLI
5 | To update the Gulp CLI to work with Gulp 4, run the following commands in the command line terminal:
6 | ```
7 | # Uninstall Gulp globally:
8 | npm uninstall gulp -g
9 |
10 | # Install the latest version of the Gulp 4 CLI globally:
11 | npm install gulpjs/gulp-cli -g
12 | ```
13 | You may have to run `npm install` again from the WP Rig directory to ensure Gulp 4 is installed and ready to run.
14 |
--------------------------------------------------------------------------------
/documentation/troubleshooting/css-grid.md:
--------------------------------------------------------------------------------
1 | # CSS Grid fallbacks for legacy browsers
2 |
3 | WP Rig uses CSS grid for global two-dimensional layouts. While `grid` has [widespread support in modern browsers](https://caniuse.com/#search=grid), some older browsers, in particular IE 11, 10, and older do not support the current specification.
4 |
5 | If support for layouts in older browsers is needed, the recommendation is to create graceful degradation fallbacks to `flex`. Below you will find some resources on creating such fallbacks:
6 |
7 | - [CSS Grid Fallbacks and Overrides](https://rachelandrew.co.uk/archives/2017/03/20/css-grid-fallbacks-and-overrides/) (Rachel Andrew)
8 | - [CSS Grid Layout and Progressive Enhancement](https://rachelandrew.co.uk/archives/2017/03/20/css-grid-fallbacks-and-overrides/) (MDN)
9 | - [Basic grid layout with fallbacks using feature queries](https://www.chenhuijing.com/blog/basic-grid-with-fallbacks/) (Chen Hui Jing)
10 |
--------------------------------------------------------------------------------
/documentation/recommended-extensions.md:
--------------------------------------------------------------------------------
1 | # Recommended code editor extensions
2 |
3 | To take full advantage of the features in WP Rig, your code editor needs support for the following features:
4 |
5 | - [EditorConfig](http://editorconfig.org/#download)
6 | - [ESLint](https://eslint.org/docs/user-guide/integrations)
7 | - [PHP CodeSniffer (phpCS)](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki)
8 |
9 | ## VS Code extensions
10 | For [VS Code](https://code.visualstudio.com/) users, here's a list of recommended code editor extensions.
11 |
12 | - [EditorConfig](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig)
13 | - [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
14 | - [PHP Debug](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug)
15 | - [PHP IntelliSense](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-intellisense)
16 | - [PHPCS](https://marketplace.visualstudio.com/items?itemName=ikappas.phpcs)
17 | - [stylelint](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint)
18 | - [POSTCSS Language Support](https://marketplace.visualstudio.com/items?itemName=csstools.postcss)
19 |
20 | To enable PHPCS in VS Code, [follow these instructions](https://wprig.io/learn/set-up-your-development-environment-v2/).
21 |
--------------------------------------------------------------------------------
/documentation/PHPCS.md:
--------------------------------------------------------------------------------
1 | # Enabling PHPCodeSniffer (PHPCS) in VS Code
2 |
3 | WP Rig runs PHPCodeSniffer (PHPCS) as part of its build process to make sure all PHP complies with [WordPress Coding Standards](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards). Any errors or warnings found by PHPCS are displayed in the command line terminal as the various WP Rig tasks run.
4 |
5 | To capture (and visualize) errors and warnings in VS Code as you are developing with WP Rig, you can activate the PHPCS extension and configure it to use the WP Rig settings:
6 |
7 | In VS Code, select extensions and search for "phpcs" and install the free [PHPCS extension](https://marketplace.visualstudio.com/items?itemName=ikappas.phpcs) from the Visual Studio Marketplace.
8 |
9 | In VS Code, open Workspace Settings (Ctrl+, on Windows, CMD+, on Mac) and add the following configuration settings:
10 |
11 | ```json
12 | {
13 | "phpcs.enable": true,
14 | "phpcs.composerJsonPath": "[path]/[to]/composer.json",
15 | "phpcs.standard": "WordPress",
16 | "editor.renderWhitespace": "all"
17 | }
18 | ```
19 | Make sure the path in `phpcs.composerJsonPath` points at the `composer.php` file in your WP Rig folder _relative to the open project folder_ in VS Code. So if you opened `users/documents/mysite/` as your project folder and your WP Rig theme sits in `wp-content/themes/mytheme/`, the value should be `./wp-content/themes/mytheme/composer.json`.
20 |
21 | With PHPCS configured in VS Code you will see green or red squiggly lines under any PHP which does not match the WordPress Coding Standards, and hovering your mouse over the highlighted code will open a tooltip telling you why PHPCS flagged this piece of code.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WP Rig Docs
2 | This repository holds documents and documentation for WP Rig.
3 |
4 | ## Documents
5 | - :page_facing_up: [WP Rig Governance](https://github.com/wprig/docs/blob/master/GOVERNANCE.md)
6 | - :page_facing_up: [WP Rig Code of Conduct](https://github.com/wprig/docs/blob/master/CODE_OF_CONDUCT.md)
7 |
8 | ## Documentation Table of Contents
9 | - :page_facing_up: [Advanced Features (and how to use them)](https://github.com/wprig/docs/blob/master/documentation/Advanced-Features-(and-how-to-use-them).md)
10 | - :page_facing_up: [Using BrowserSync with WP Rig](https://github.com/wprig/docs/blob/master/documentation/BrowserSync.md)
11 | - :page_facing_up: [Enabling PHPCodeSniffer (PHPCS) in VS Code](https://github.com/wprig/docs/blob/master/documentation/PHPCS.md)
12 | - :page_facing_up: [CSS in WP Rig](https://github.com/wprig/docs/blob/master/documentation/css.md)
13 | - :page_facing_up: [CSS grid fallbacks for legacy browsers](https://github.com/wprig/docs/blob/master/documentation/troubleshooting/css-grid.md)
14 | - :page_facing_up: [Recommended Git Workflow](https://github.com/wprig/docs/blob/master/documentation/git-workflow.md)
15 | - :page_facing_up: [Gulp in WP Rig](https://github.com/wprig/docs/blob/master/documentation/gulp.md)
16 | - :page_facing_up: [PHP Architecture in WP Rig](https://github.com/wprig/docs/blob/master/documentation/php.md)
17 | - :page_facing_up: [Recommended code editor extensions](https://github.com/wprig/docs/blob/master/documentation/recommended-extensions.md)
18 | - :open_file_folder: [Troubleshooting](https://github.com/wprig/docs/tree/master/documentation/troubleshooting)
19 | - :page_facing_up: [Updating to Gulp 4](https://github.com/wprig/docs/blob/master/documentation/troubleshooting/gulp4.md)
20 |
21 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # WP Rig Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at info@wprig.io. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/documentation/BrowserSync.md:
--------------------------------------------------------------------------------
1 | # Using BrowserSync with WP Rig
2 |
3 | WP Rig uses [BrowserSync](https://browsersync.io/) to enable synchronized browser testing. To take advantage of this feature, configure the `browserSync` wrapper settings in `./dev/config/themeConfig.js` to match your local development environment. The `proxyURL` value is the URL to the live version of your local site.
4 |
5 | ## Enabling HTTPS
6 |
7 | In order to enable HTTPS with BrowserSync, you must supply a valid certificate and key with the Subject Alternative Name of `localhost`. Common Name has been deprecated since 2000 ([details](https://www.chromestatus.com/features/4981025180483584)).
8 |
9 | WP Rig can generate a key and certificate valid for `localhost` for you with the command `npm run generateCert`. The key and certificates will be saved as `BrowserSync/wp-rig-browser-sync-key.key`, `BrowserSync/wp-rig-browser-sync-root-cert.crt` and `BrowserSync/wp-rig-browser-sync-cert.crt` in the WP Rig theme directory.
10 |
11 | To use the generated key and certificate across multiple projects copy `BrowserSync/wp-rig-browser-sync-key.key`, `BrowserSync/wp-rig-browser-sync-root-cert.crt` and `BrowserSync/wp-rig-browser-sync-cert.crt` in the WP Rig theme directory to a global location, such as your home directory, uncomment and update the `keyPath` and `certPath` values in `dev/config/themeConfig.js` with the absolute paths for the key and certificate.
12 |
13 | Then in future WP Rig projects you can simply set `https` to `true` and uncomment and update `keyPath` and `certPath` in `dev/config/themeConfig.js` with the paths of your existing key and certificate files rather than generating new ones for each project. Note that the certificate must be signed with an accompanying CA certificate and both certificates need to be trusted.
14 |
15 | Unless `keyPath` and `certPath` are explicitly defined, the default paths of `./BrowserSync/wp-rig-browser-sync-key.key` and `./BrowserSync/wp-rig-browser-sync-cert.crt` in the WP Rig theme directory will be used.
16 |
17 | To use the default key and cert generated above, create new config settings in `./config/config.json` as follows:
18 |
19 | ```
20 | {
21 | "dev": {
22 | "browserSync": {
23 | "live": true,
24 | "proxyURL": 'localwprig.com',
25 | "bypassPort": '8181',
26 | "https": true
27 | }
28 | }
29 | ```
30 |
31 | ### Disable SSL certificate warnings
32 |
33 | In addition, to disable SSL certificate warnings in the browser you will need to trust the certificate and CA certificate.
34 |
35 | **For macOS:**
36 | 1. Open Keychain Access.
37 | 2. Drag the certificate file, which if using `npm run generateCert` to generate the certificates is saved to `BrowserSync/wp-rig-browser-sync-cert.crt`, into KeyChain access.
38 | 3. Double click on the new `WP Rig` certificate in the list, might also be labelled `localhost`.
39 | 4. Expand the `trust` menu.
40 | 5. Change the `When using this certificate:` setting to `Always Trust`.
41 | 6. Close the certificate dialogue.
42 | * You may be prompted for your computer password to save the setting.
43 | * If not, close the window and you will receive the prompt.
44 | 7. Repeat steps 3 through 6 for any other certificates.
45 |
46 | Note that these steps only need to be done once for each key and certificate. The generated key and certificates expire after 5 years, at which point you will need to generate new ones and follow the steps above again.
47 |
48 | **Screenshots of Keychain Access**
49 |
50 | 
51 |
52 | ### Troubleshooting
53 |
54 | **Enabling HTTPS with Firefox**
55 | Navigate to `about:preferences` in Firefox, scroll down to the bottom of the page under Certificates -> View Certificates.
56 |
57 | 
58 |
59 | First, make sure the `Authorities` tab is active in the top nav bar.
60 |
61 | 
62 |
63 | Second, click the middle bottom row Import -> navigate to directory of the of the certificates (wprig defaults to `/BrowserSync` select the root certificate `wp-rig-browser-sync-root-cert.crt` and import. If you are unable to select the certificate file, click the `options` tab to make sure `Certificate` file type is selected.
64 |
65 | 
66 |
--------------------------------------------------------------------------------
/documentation/Advanced-Features-(and-how-to-use-them).md:
--------------------------------------------------------------------------------
1 | # Advanced Features (and how to use them)
2 |
3 | WP Rig gives the developer an out of the box environment with support for modern technologies including ES2015, CSS grid, CSS custom properties (variables), and existing tools like Sass without making any configurations. Just write code and WP Rig handles the heavy lifting for you.
4 |
5 | ## WP Rig features
6 | WP Rig takes a component-based approach to WordPress themes. Out of the box, the compiled theme uses `index.php` as the core template file for all views (index, archives, single posts, pages, etc).
7 |
8 | The `/optional` folder holds optional template files that can be accessed via the [WordPress Template Hierarchy](https://developer.wordpress.org/themes/basics/template-hierarchy/). To activate these files, move or copy them into the root `wp-rig` theme folder. The `/optional` folder is ignored by the Gulp build process.
9 |
10 | The separation of Pluggable and External features into their own folders allows the theme developer to swap out any feature for an external feature (AMP components) or non-php feature (JavaScript framework etc) without interfering with the core theme functions.
11 |
12 | Pluggable functions and features (eg custom header, sliders, other interactive components) are separated into the `/pluggable` folder for easy access. When custom stylesheets and/or JavaScript files are needed, the pluggable component and its dependent files should be placed in a sub-folder to retain separation of concerns.
13 |
14 | External features and add-ons are separated into the `/external` folder and are managed the same way as Pluggable functions.
15 |
16 | Images and graphics are placed in the `/images` folder and are optimized automatically.
17 |
18 | Global JavaScript files are placed in the `/js` folder and linted and optimized automatically. External JavaScript libraries are placed in the `/js/libs` folder. _These files are not linted or optimized by the Gulp process_.
19 |
20 | Global stylesheets and stylesheets related to root-level php files are placed in the `/css` folder and are optimized automatically.
21 |
22 | Content loop files are placed in the `/template-parts` folder.
23 |
24 | `style.css` is required for WordPress to detect the theme but it is not used.
25 |
26 | ## Progressive Features
27 |
28 | ### Lazy-loading images
29 | WP Rig [lazy loads](https://developers.google.com/web/fundamentals/performance/lazy-loading-guidance/images-and-video/) all images out of the box to improve performance. When lazy-loading images is enabled in the theme, the user will see a Theme Options feature in Customizer allowing them to toggle the feature off.
30 | To disable this feature in the theme, comment out or remove the following line from `./functions.php`:
31 |
32 | ```php
33 | require get_template_directory() . '/pluggable/lazyload/lazyload.php';
34 | ```
35 |
36 | ### AMP-ready
37 | The theme generated by WP Rig is AMP-ready meaning it works hand-in-hand with the official AMP plugin and does not require further configuration to work with AMP features. The AMP plugin allows you to [opt-in to `amp` theme support via the plugin settings page](https://github.com/Automattic/amp-wp/wiki/Adding-Theme-Support) but you can also force enable AMP support in a theme by adding `add_theme_support( 'amp' );` in `./functions.php`.
38 |
39 | #### AMP and custom JavaScript
40 | When AMP support is enabled, JavaScript and other features are automatically disabled if the site admin has enabled the [official AMP plugin](https://en-ca.wordpress.org/plugins/amp/). Developers can selectively enable/disable features within the theme using the `wprig_is_amp()` conditional. For more see [Implementing Interactivity](https://github.com/Automattic/amp-wp/wiki/Implementing-Interactivity).
41 |
42 | ### Progressive loading of CSS
43 | To further componentize the theme, WP Rig employs progressive loading of CSS through [in-body `` tags](https://jakearchibald.com/2016/link-in-body/). Component-specific styles are held in component-specific stylesheets and loaded at component level. The `wprig_add_body_style()` in `./inc/template-functions.php` can be used to conditionally preload in-body stylesheets for improved performance.
44 | This approach has several advantages:
45 | - The main stylesheet file size is reduced
46 | - Styles are only loaded if and when a component is present in the view.
47 | - Stylesheets are associated with their components making them easier to work with.
48 | - Leverages HTTP/2 multiplexing and can be extended to include server push etc.
49 | - Component-level stylesheets are cached and can be individually updated without forcing reload of all styles on the site.
50 |
51 | To improve the performance of the theme, progressively loaded stylesheets can be conditionally preloaded. This is done using the `wprig_add_body_style()` function in `./inc/template-functions.php`. When preloading a stylesheet, use the console in Chrome developer tools to ensure no unnecessary stylesheets are loaded. A warning will appear letting you know if a stylesheet is preloaded but not used.
52 |
53 | ### Modern CSS, custom properties (variables), autoprefixing, etc
54 | All CSS is processed through [PostCSS](http://postcss.org/) and leveraging [postcss-preset-env](https://preset-env.cssdb.org/) to allow the use of modern and future CSS markup like [custom properties (variables)](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables). Variables are defined in `./config/cssVariables` and applied to all CSS files as they are processed.
55 | postcss-preset-env (previously cssnext) passes all CSS through Autoprefixer to ensure backward compatibility. [Target browsers](https://github.com/browserslist/browserslist) are configured under `browserlist` in `./config/cssVariables`.
56 |
57 | ### Modern layouts through CSS grid, flex, and float
58 | The theme generated by WP Rig is mobile-first and accessible. It uses the modern layout modules CSS grid and flex to support a minimalist HTML structure.
59 |
60 | For backward compatibility with browsers who do not support modern layout modules, WP Rig provides the mobile-first layout across all screen widths and serves two-dimensional layouts as a progressive enhancement.
61 |
62 | The CSS philosophy of WP Rig breaks down as follows:
63 | - Mobile layout for all screen sizes as fallback.
64 | - Two-dimensional layouts using CSS grid.
65 | - One dimensional block/list-based displays using flex.
66 | - In-content wrapping using float and clear.
67 |
--------------------------------------------------------------------------------
/documentation/git-workflow.md:
--------------------------------------------------------------------------------
1 | # Recommended Git Workflow
2 |
3 | WP Rig is constantly being improved to stay on top of the modern web and how it evolves. As such, it is crucial that you are able to pull in these latest improvements when building your own WP Rig-based theme. In order to accomplish that, WP Rig has to break conventions for how you develop your theme. In this article you will learn about what the recommended git workflow with WP Rig looks like.
4 |
5 | ## What is different?
6 |
7 | When developing your theme based on WP Rig, you should continue to use the original "WP Rig" prefixes for all functions, classes, etc. Historically, when building a theme you would probably have used prefixes based on the name of your own theme. However, don't worry - with WP Rig you still get to brand your theme (including its code) with your own theme name. The build process includes an easy-to-use command that you can run to copy your development theme into a different folder in its production-ready version. And in that version all occurrences of "WP Rig" (or related prefixes) will have been replaced with your own ones.
8 |
9 | ## Why is that necessary?
10 |
11 | When relying on other starter themes such as [Underscores (_s)](http://underscores.me), you will generate your base for developing a new theme once when you start. Underscores will take care of making all the replacements for you right away. This approach leads to one significant problem: You will never be able to update your theme with upstream changes that have been made to Underscores since you first generated your base, unless you're willing to go through a fully manual and time-consuming process.
12 |
13 | WP Rig breaks with that paradigm: Prefixes remain "WP Rig", so you can easily pull in upstream changes that have been added to WP Rig after you started building your theme from it. This allows you to stay up to date also in the future. At the same time, your production-ready version of the theme will still use your own naming and prefixes as you envision it, so you don't actually lose anything.
14 |
15 | ## How does it work?
16 |
17 | Here are some step-by-step guides on the recommended workflow with WP Rig. For the sake of this guide, let's assume your theme will be called "Morten", and your GitHub username is "wpdev".
18 |
19 | ### Setting up your own theme based on WP Rig
20 |
21 | Here's what you need to do to set up your new theme based on WP Rig:
22 |
23 | 1. [Create a new GitHub repository](https://github.com/new) on your account called "morten".
24 | 2. Clone WP Rig into a local directory where you'll be developing in. Name that directory after your own theme followed by a suffix indicating it is the development version, e.g. "morten-dev" (`git clone git@github.com:wprig/wprig.git wp-content/themes/morten-dev`).
25 | 3. Go into that directory (`cd wp-content/themes/morten-dev`).
26 | 4. Delete the original WP Rig connection from your local repository (`git remote remove origin`).
27 | 5. Connect your local repository to your own GitHub project (`git remote add origin git@github.com:wpdev/morten.git`).
28 | 6. Re-add the connection to WP Rig as an upstream (`git remote add upstream git@github.com:wprig/wprig.git`).
29 | 7. Edit the configuration file `config/config.json` and add your own custom configuration based on `config/config.default.json` as necessary (most importantly make sure to update all values in the `theme` section). For an easy start, you could just copy the entire default configuration and then update it (`rm config/config.json && cp config/config.default.json config/config.json`).
30 | 8. Run `composer install` to install the necessary PHP dependencies.
31 | 9. Run `npm install` to install the necessary JavaScript dependencies.
32 | 10. Run `npm run build` to create a first build of your theme.
33 | 11. Create a first custom commit from your changes (`git add . && git commit -m "Customize configuration."`).
34 | 12. Push the changes to your own repository (`git push -u origin master`).
35 | 13. You're good to go now. Just make changes, commit them, and push them regularly.
36 |
37 | ### Creating a production-ready version of your theme
38 |
39 | Remember: Don't bother manually replacing all the "WP Rig", "wp_rig_", etc. references in the codebase - for the development version of your theme, leave them as they are. Creating a production-ready version of your theme that you can then use on your website or release on wordpress.org) is fairly simple:
40 |
41 | 1. Run `npm run bundle` to create your production-ready version.
42 | 2. After the command has finished, a new directory with your theme slug (e.g. `morten`) will have been created at the same level as your development theme. That folder is ready as-is for you to deploy anywhere you like.
43 |
44 | ### Updating with upstream WP Rig changes
45 |
46 | Every once in a while, you should update your development theme with the latest improvements that WP Rig has received in the meantime. WP Rig is generally developed in a backward-compatible way, with the exception of major versions (a.k.a. 2.0, 3.0, 4.0), which introduce breaking changes. So unless WP Rig has seen such a version bump, you can typically merge in upstream changes easily. Depending on how much you changed significantly in your theme, there is always a change for merge conflicts. Nonetheless, it's good to be aware of the possibility. As a general rule of thumb, pulling in changes regularly helps keeping the maintenance of updates low. If you only update once every 3 months, it's more likely you will run into a few merge conflicts, so you might need to dedicate one or two hours to it then. However, keep in mind that with the old paradigm of theme development you would never have updated at all, so your theme would have gotten out of date easily. Here is what you need to do to merge in the latest updates from WP Rig:
47 |
48 | 1. Update the latest upstream master branch (`git pull upstream master`).
49 | 2. Merge in the latest upstream changes to your own project's master branch (`git merge upstream/master`).
50 | 3. If any merge conflicts occur, you need to resolve them in order to complete the merge.
51 |
52 | ### Updating your theme using WP Rig as your template repository
53 |
54 | If you have opted to use WP Rig as a template theme for your theme and would like to update it with all the new changes from WP Rig it is now really easy to do. After pulling in the new code you will probably have to spend some time going through any merge conflicts.
55 |
56 | 1. Run (`git remote add template https://github.com/wprig/wprig.git`). This goes ahead and add the master branch of WP Rig as a template to your project.
57 | 2. Run (`git remote -v`) to check to make sure that the template versions was added. You should see:
58 | `origin https://github.com/user/your-theme.git (fetch)
59 | origin https://github.com/user/your-theme.git (push)
60 | template https://github.com/wprig/wprig.git (fetch)
61 | template https://github.com/wprig/wprig.git (push)`
62 | 3. Run (`git pull --tags template master`)
63 |
--------------------------------------------------------------------------------
/documentation/gulp.md:
--------------------------------------------------------------------------------
1 | # Gulp in WP Rig
2 |
3 | WP Rig uses a [gulp](https://gulpjs.com/) to assist in development and to generate and optimize code for production use. This article is an in-depth explanation of the gulp processes in WP Rig. If you want to know how to install WP Rig and get started see `README.md`.
4 |
5 | ## Background
6 |
7 | As of version `2.0` WP Rig is meant to be edited as a development, or source, theme. Once development is complete WP Rig can generate a production version of the code, without the pieces needed for development. This is done to optimize both the development workflow as well as the production theme.
8 |
9 | One of the slowest parts of the gulp process in version `1` of WP Rig was string replacement related tasks. With version `2` string replacement does not happen during development, only when the production theme is built.
10 |
11 | Version `1` of WP Rig also used a `dev` subdirectory rather than a source and production structure. This approach is counter-intuitive to how WordPress themes are traditionally developed. Being able to edit any PHP file in WP Rig version `2`, without needing to know to only edit the ones in `dev`, will help lower the barrier to entry for developers new to WP Rig.
12 |
13 | Version `2` of WP Rig also took the monolithic `gulpfile.babel.js` from version `1` and replaced it with more modular files, incorporating modern JavaScript best practices.
14 |
15 | ## Running `gulp` Tasks
16 |
17 | The main gulp tasks, listed below, are run using [`npm scripts`](https://docs.npmjs.com/misc/scripts). This ensures that the gulp binary downloaded with npm is used.
18 |
19 | - `npm run dev`
20 | - Processes all source files and watches files for subsequent changes.
21 | - `npm run build`
22 | - Processes all source files once-time and does not watch for changes.
23 | - `npm run bundle`
24 | - Creates a production version of the theme, saved to a separate directory in `wp-content/theme`, that does not include any unnecessary development files, such as asset source files.
25 | - `npm run generateCert`
26 | - Generates `localhost` SSL certificates for use with the BrowerSync proxy server.
27 | - `npm run translate`
28 | - Generates a `.pot` file based on the theme PHP files
29 |
30 | gulp tasks not specifically mapped with npm script can still be run using the format `npm run dev -- `, replacing `` with the actual gulp task name. For example, `npm run dev -- images` will run the image task.
31 |
32 | Available gulp tasks suitable to be run independently are:
33 |
34 | - `images`
35 | - `php`
36 | - `scripts`
37 | - `styles`
38 | - `editorStyles`
39 |
40 |
41 | Explanations of each gulp task are detailed in the next section of this article.
42 |
43 | ## gulp Tasks and Files
44 |
45 | ### gulpfile.babel.js
46 |
47 | `gulpfile.babel.js` is the main gulp file. Using `gulpfile.babel.js` instead of `gulpfile.js` tells gulp to process the file with [Babel](https://babeljs.io/). This allows modern JavaScript to be used when writing the gulp functions themselves.
48 |
49 | The purpose of `gulpfile.babel.js` is to define all available gulp tasks. This is done by exporting a named function for each task.
50 |
51 | The main functions doing work are defined in separate files in the `gulp` directory and imported at the top of `gulpfile.babel.js`. Larger functions, using gulp `parallel` and `series` to define a specific order for the smaller functions, are then defined. Theme larger functions are then exported so that they become gulp tasks.
52 |
53 | All of the smaller imported functions are exported as-is as well to allow them to be run as independent gulp tasks if desired.
54 |
55 | ## Other gulp files
56 |
57 | ### constants.js
58 |
59 | `constants.js` is where constants for use in other gulp files are defined. Mainly this consists of file paths so that they do not need to be defined each time they are used and can easily be changed in one file.
60 |
61 | ### utils.js
62 |
63 | `utils.js` is a collection of utility functions that other gulp functions make use of. If logic was repeated in multiple gulp functions it was moved here to avoid repetition.
64 |
65 | ### browserSync.js
66 |
67 | `browserSync.js` defined [BrowserSync](https://www.browsersync.io/) related functions. Mainly, a BrowserSync proxy server. There is also a reload function which will refresh the BrowserSync server instance.
68 |
69 | ### generateCert.js
70 |
71 | `generateCert.js` uses [`create-cert`](https://www.npmjs.com/package/create-cert) to programmatically generate SSL certificates for `localhost`. These certificates are required to use HTTPS with the BrowserSync server.
72 |
73 | ### images.js
74 |
75 | `images.js` uses [`gulp-imagemin`](https://www.npmjs.com/package/gulp-imagemin) to optimized images.
76 |
77 | ### php.js
78 |
79 | `php.js` reads PHP files and, optionally, uses [PHP Code Sniffer](https://github.com/squizlabs/PHP_CodeSniffer) to check them against [WordPress Coding Standards](https://github.com/WordPress-Coding-Standards).
80 |
81 | If gulp is being run in production mode then the PHP files have the WP Rig name replaced and are saved to the production directory, in addition to the steps above.
82 |
83 | ### scripts.js
84 |
85 | `scripts.js` reads JavaScript source files, uses [ESLint](https://eslint.org/) to check them against [WordPress Coding Standards](https://github.com/WordPress-Coding-Standards), transpiles the files with [Babel](https://babeljs.io/), and saves a minified version to the assets directory.
86 |
87 | If gulp is being run in production mode then the optimized JavaScript files have the WP Rig name replaced and are saved to the production directory, in addition to the steps above.
88 |
89 | ### styles.js
90 |
91 | `styles.js` reads CSS source files, uses [PHP Code Sniffer](https://github.com/squizlabs/PHP_CodeSniffer) to check them against [WordPress Coding Standards](https://github.com/WordPress-Coding-Standards), transpiles the files with [PostCSS](https://postcss.org/), and saves a minified version to the assets directory.
92 |
93 | If gulp is being run in production mode then the optimized CSS files have the WP Rig name replaced and are saved to the production directory, in addition to the steps above.
94 |
95 | ### editorStyles.js
96 |
97 | `editorStyles.js` runs the same process as `styles.js`, except it used `editor-styles.css`, which is enqueued for the block editor in the WordPress admin. Styles placed here are ones necessary for the block editor but not the front-end of the site.
98 |
99 | ### translate.js
100 |
101 | `translate.js` reads the theme PHP files and uses `gulp-wp-pot` to generate a `.pot` file.
102 |
103 | ### watch.js
104 |
105 | `watch.js` watches PHP, JS, CSS, image and configuration files. When they are changed the proper tasks are re-run and the BrowserSync server reloads.
106 |
107 | ### prodPrep.js
108 |
109 | `prodPrep.js` is run if gulp is in production mode before other file processing tasks are run. The production directory is created and necessary files that are not otherwise processed with gulp, such as `readme.txt`, are copied to the production theme.
110 |
111 | ### prodFinish.js
112 |
113 | `prodFinish.js` is run if gulp is in production mode after other file processing tasks are run and a `.zip` file of the production theme is created.
114 |
--------------------------------------------------------------------------------
/GOVERNANCE.md:
--------------------------------------------------------------------------------
1 | # Governance
2 |
3 | [WP Rig](https://github.com/wprig/wprig/) is an open source project that depends on contributions from the community. As long as they abide by the project’s [Code of Conduct](https://github.com/wprig/docs/blob/master/CODE_OF_CONDUCT.md), anyone may contribute to the project at any time by submitting code, participating in discussions, making suggestions, or any other contribution they see fit. This document describes how various types of contributors work within the WP Rig project and how decisions are made.
4 |
5 | ## Roles and Responsibilities
6 |
7 | ### Community members
8 | _Everyone_ who is involved in any form with the project must abide by the project’s [Code of Conduct](https://github.com/wprig/docs/blob/master/CODE_OF_CONDUCT.md). Everyone is expected to be respectful of fellow community members and to work collaboratively respective of the Code of Conduct. Consequences for not adhering to these Guidelines are listed in their respective documents.
9 |
10 | ### Users
11 | Users are community members who have a need for the project. They are typically developers building WordPress themes. Anyone can be a User; there are no special requirements and WP Rig is licensed under [GPL v3.0](https://github.com/wprig/wprig/blob/master/LICENSE). Common User contributions include using WP Rig to build themes, evangelizing the project (e.g., display a link on a website and raise awareness through word-of-mouth), informing developers of strengths and weaknesses from a new user perspective, or providing moral support (a “thank you” goes a long way).
12 |
13 | Users who continue to engage with the project and its community will often become more and more involved. Such Users may find themselves becoming [Contributors](#Contributors), as described in the next section.
14 |
15 | ### Contributors
16 | Contributors are community members who contribute in concrete ways to the project, most often in the form of code and/or documentation submitted through [Pull Requests](https://help.github.com/en/articles/about-pull-requests) (PRs) to the [`develop` branch of the WP Rig GitHub repository](https://github.com/wprig/wprig/tree/develop). Anyone can become a Contributor, and contributions can take many forms. There is no expectation of commitment to the project, no specific skill requirements, and no selection process. Contributors must follow the [Code of Conduct](https://github.com/wprig/docs/blob/master/CODE_OF_CONDUCT.md).
17 |
18 | Contributors:
19 | - Have read-only access to source code and therefore can submit changes via pull requests.
20 | - Have their contribution reviewed and merged by a [Maintainer](#Maintainers) or [Owner](#Owners). Owners and Maintainers work with Contributors to review their code and prepare it for merging.
21 | - May also comment on issues and pull requests. While their approval or disapproval is not decisive, it is a good way to provide feedback to those making decisions.
22 |
23 | As Contributors gain experience and familiarity with the project, their profile within, and commitment to, the community will increase. At some stage, they may find themselves being nominated for becoming a Maintainer by an existing Maintainer or Owner.
24 |
25 | ### Maintainers
26 | Maintainers are community members who have shown that they are committed to the continued development of the project through ongoing engagement with the community. Maintainers are given push/write access to the project’s GitHub repos.
27 |
28 | Maintainers:
29 |
30 | - Are expected to work on public branches of their forks and submit pull requests to the `development` branch.
31 | - Must submit pull requests for all their changes.
32 | - May label and close issues.
33 | - May only merge other people's pull requests once the PR has been approved by two other Maintainers.
34 | - Should ask for additional review from other Maintainers or Owners on other people's PRs that are disruptive or controversial.
35 |
36 | To become a Maintainer one must:
37 |
38 | - Have shown a willingness and ability to participate in the project in a helpful and collaborative way with the WordPress community.
39 | - Typically, a potential Maintainer will need to show that they have an understanding of and alignment with the project, its objectives, and its strategy.
40 | - Have contributed a significant amount of work to the project (e.g. in the form of PRs or PR reviews), thereby demonstrating their trustworthiness and commitment to the project.
41 | - Read and agree to abide by the [Code of Conduct](https://github.com/wprig/docs/blob/master/CODE_OF_CONDUCT.md).
42 | - File an issue in the [wprig/wprig](https://github.com/wprig/wprig) repository and record “I have read, and agree to abide by, the [WP Rig Code of Conduct].”
43 |
44 | New Maintainers can be nominated by any existing Maintainers. Once they have been nominated, there will be a vote by the Maintainers.
45 |
46 | It is important to recognize that being a Maintainer is a privilege, not a right. That privilege must be earned and once earned it can be removed by a majority vote by the Maintainers. However, under normal circumstances the Maintainer status exists for as long as the Maintainer wishes to continue engaging with the project. Inactive Maintainers (no activity on the project for longer for 4 months or more) might be marked as inactive or removed after a majority vote of Maintainers and may re-enter when they choose to contribute again.
47 |
48 | #### List of current peers
49 | - Andrew Taylor (@ataylorme)
50 | - Benoit Chantre (@benoitchantre)
51 | - Felix Arntz (@felixarntz)
52 | - Morten Rand-Hendriksen (@mor10)
53 | - Rachel Cherry (@bamadesigner)
54 |
55 | A Maintainer who shows an above-average level of contribution to the project, particularly with respect to its strategic direction and long-term health, may be nominated to become an Owner, described below.
56 |
57 | ### Owners
58 | The WP Rig project is governed by the [Owner group](#list-of-current-owners). They are collectively responsible for high-level guidance of the project.
59 |
60 | The [Owner group](#list-of-current-owners) has final authority over this project including:
61 |
62 | - Technical direction of the project, especially infrastructure PRs and linting and/or schema decisions.
63 | - Project governance and process (including this policy and any updates).
64 | - Contribution policy.
65 | - GitHub repository hosting.
66 |
67 | Being an Owner is not time-limited. There is no fixed size of the Owner group. The Owner group should be of such a size as to ensure adequate coverage of important areas of expertise balanced with the ability to make decisions efficiently.
68 | An Owner may be removed from the Owner group by voluntary resignation, or by a standard Owner group motion, including for violations of Code of Conduct.
69 |
70 | Changes to the Owner group should be posted in the agenda, and may be suggested as any other agenda item (see [Project Meetings](#project-meetings) below).
71 |
72 | Owners fulfill all requirements of Maintainers, and also:
73 |
74 | - Ensure the smooth running of the project.
75 | - Approve changes to this document.
76 | - Manage and merge commits to the `master` branch.
77 |
78 | To become an Owner one must fulfill at least the following conditions and commit to being a part of the community for the long-term.
79 |
80 | - Have worked in a helpful and collaborative way with the WordPress and WP Rig communities.
81 | - Have given good feedback on others’ submissions and displayed an overall understanding of the code quality standards for the project.
82 | - Have the ability to drive the project forward, manage requirements from users, and taking on responsibility for the overall health of the project.
83 |
84 | An individual is invited to become an Owner by existing Owners. A nomination will result in discussion and then a decision by the Owner group.
85 |
86 | #### List of current Owners
87 | - Morten Rand-Hendriksen (@mor10)
88 | - Rachel Cherry (@bamadesigner)
89 |
90 | ## Decision Making
91 | Decision making generally follows a [Consensus-seeking decision-making](https://en.wikipedia.org/wiki/Consensus-seeking_decision-making) model.
92 |
93 | When an agenda item has appeared to reach a consensus, the moderator will ask “Does anyone object?” as a final call for dissent from the consensus.
94 |
95 | If an agenda item cannot reach a consensus, an owner can call for either a closing vote or a vote to table the issue to the next meeting. The call for a vote must be approved by a majority of the owners or else the discussion will continue. Simple majority wins.
96 |
97 | ## Project Meetings
98 | There are bi-weekly project meetings; they are scheduled in a [shared calendar](https://calendar.google.com/calendar/embed?src=wprigio%40gmail.com&ctz=America%2FChicago), and using tools that enable participation by the community.
99 |
100 | ## Credits
101 | This work is a derivative of [MDN Browser Compat Data GOVERNANCE](https://github.com/mdn/browser-compat-data/blob/master/GOVERNANCE.md), a derivative of [ESLint Governance](https://github.com/eslint/eslint.github.io/blob/master/docs/maintainer-guide/governance.md), [YUI Contributor Model](https://github.com/yui/yui3/wiki/Contributor-Model), and the [JS Foundation TAC Charter](https://github.com/JSFoundation/TAC).
102 |
--------------------------------------------------------------------------------
/documentation/css.md:
--------------------------------------------------------------------------------
1 | # CSS in WP Rig
2 |
3 | ## Table of contents:
4 | - [WP Rig CSS philosophy](#wp-rig-css-philosophy)
5 | - [Layouts](#layouts)
6 | - [File structure and CSS modules](#file-structure-and-css-modules)
7 | - [Modern CSS via PostCSS](#modern-css-via-postcss)
8 | - [CSS Grid](#css-grid)
9 | - [Custom Properties (variables)](#custom-properties)
10 | - [Custom Media (queries)](#custom-media)
11 | - [Nesting](#nesting)
12 | - [Why no Sass support?](#why-no-sass-support)
13 | - [Progressive loading of CSS](#progressive-loading-of-css)
14 | - [Code linting](#code-linting)
15 | ## WP Rig CSS philosophy
16 | WP Rig promotes modern CSS best-practices by enabling developers to write and use modern CSS today and take advantage of upcoming CSS features even when these are not yet available in browsers. WP Rig uses pure CSS markup without pre-processors. The CSS provided by WP Rig follows these principles:
17 | - Accessible
18 | - Mobile-first
19 | - Modular
20 | - Performance optimized
21 | - Compliant with [WordPress Coding Standards](https://make.wordpress.org/core/handbook/best-practices/coding-standards/css/).
22 | ### Layouts
23 | WP Rig uses the modern layout modules [CSS grid](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout) and [flex](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox) to support a minimalist HTML structure. The mobile-first layout serves as the baseline across all screen widths, and two-dimensional layouts are served as a progressive enhancement. As a result, browsers without grid/flex support are served with the mobile layout.
24 |
25 | The layouts in WP Rig follow these design principles:
26 | - Mobile layout for all screen sizes as baseline and fallback for older browsers.
27 | - Two-dimensional layouts using CSS grid.
28 | - One dimensional block/list-based displays using flex.
29 | - In-content wrapping using float and clear.
30 | ## File structure and CSS modules
31 | The file structure of CSS in WP Rig is modular with a strong focus on performance. This modular nature of the CSS files makes working with CSS easier, and improves performance thanks to progressive loading. Here’s how CSS works out of the box:
32 | - In WP Rig, `style.css` found in the root folder serves only as a container for the required theme configuration data.
33 | - All editable CSS is found under `assets/css/src/`. The contents of this folder are linted to [WordPress Coding Standards](https://make.wordpress.org/core/handbook/best-practices/coding-standards/css/) using [stylelint](https://stylelint.io/), minified, and output to `assets/css/` by the build process.
34 | - `global.css` serves as the main stylesheet. This file is loaded in the `` section of every template.
35 | - All other files without an `_` prefix are loaded conditionally by their respective components (see below).
36 | - Files prefixed by a `_` (eg `_blocks.css`) are _partials_, compiled into their parent files using `@import` rules. PostCSS imports the contents of these partials during processing to become part of the parent file.
37 | - [Editor styles](https://wordpress.org/gutenberg/handbook/designers-developers/developers/themes/theme-support/#editor-styles) are found in `assets/css/src/editor/editor-styles.css`.
38 |
39 | This modular file structure has several benefits including
40 | - discoverability (rules are grouped based on their function and/or module and easy to find)
41 | - performance (files are only loaded when used)
42 | - caching and bandwidth (individual files can be updated without the entire set of styles being updated)
43 | CSS can be modified, deleted, and/or added to all existing files in `assets/css/src/`. When files are removed or new files are added to this folder, they need to be registered with the theme for use and called from the appropriate component. See [Progressive Loading of CSS](#progressive) for further details.
44 | ## Modern CSS via PostCSS
45 | All CSS is processed through [PostCSS](http://postcss.org/) and leveraging [postcss-preset-env](https://preset-env.cssdb.org/) to allow the use of modern and future CSS markup like [custom properties (variables)](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables). postcss-preset-env support for modern features is configured by setting [stage](https://github.com/csstools/postcss-preset-env#options) and other configurations in `./config/config.default.json`:
46 | ```json
47 | "styles": {
48 | "stage": 3,
49 | "importFrom": [ "_custom-media.css" ],
50 | "features": {
51 | "custom-media-queries": true,
52 | "custom-properties": true,
53 | "nesting-rules": true
54 | }
55 | }
56 | ```
57 | These settings can be modified in `./config/config.json`
58 | PostCSS passes all CSS through [Autoprefixer](https://github.com/postcss/autoprefixer) to ensure backward compatibility based on [browserslist](https://github.com/browserslist/browserslist) settings found in `.browserslistrc`.
59 | ### CSS Grid
60 | WP Rig uses CSS grid for two-dimensional layouts, in particular the overall layout of templates with sidebars and the front page template. PostCSS, postcss-preset-env, and Autoprefixer provide robust backwards compatibility for CSS grid, but there are some caveats. To learn more about how grid is handled by PostCSS, check out these resources:
61 | - [CSS Grid in IE: CSS Grid and the New Autoprefixer](https://css-tricks.com/css-grid-in-ie-css-grid-and-the-new-autoprefixer/)
62 | - [grid in postcss-preset-env documentation](https://github.com/csstools/postcss-preset-env#autoprefixer)
63 | - [Grid autoplacement support in IE](https://github.com/postcss/autoprefixer#grid-autoplacement-support-in-ie)
64 | ### Custom Properties
65 | Modern browsers support [Custom Properties, aka CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/--*). Custom properties allow developers to declare a value once and reference this declaration throughout the stylesheet just like a regular variable in another coding language. Custom properties are scoped to the elements they are declared on, and follow the cascade, meaning a custom property can be declared, and then changed for a specific scope in a stylesheet.
66 |
67 | A prototypical example of custom properties looks like this:
68 | ```css
69 | :root {
70 | --first-color: #488cff;
71 | --second-color: #ffff8c;
72 | }
73 |
74 | #firstParagraph {
75 | background-color: var(--first-color);
76 | color: var(--second-color);
77 | }
78 | ```
79 | WP Rig uses custom properties for a long list of values including font families and sizes, and colors. The custom properties are declarations in a CSS partial at `./assets/css/src/_custom-properties.css`. This file is included at the top of `global.css`.
80 |
81 | All custom properties in WP Rig are declared using the [`:root` selector](https://developer.mozilla.org/en-US/docs/Web/CSS/:root), a pseudo-class applying to “the root element of a tree representing the document”. This means the custom properties apply to the _entire_ document. The reason for this is backwards compatibility:
82 | While modern browsers support custom properties, older browsers do not. PostCSS solves this problem by adding fallback property declarations any place a custom property is used, but this only works for custom properties declared at `:root`. The resulting CSS looks like this:
83 |
84 | ```css
85 | body,
86 | button,
87 | input,
88 | select,
89 | optgroup,
90 | textarea {
91 | color: #333;
92 | color: var(--global-font-color);
93 | font-family: "Crimson Text", serif;;
94 | font-family: var(--global-font-family);
95 | font-size: calc(20 / 16 * 1rem);
96 | font-size: var(--font-size-regular);
97 | line-height: 1.4;
98 | line-height: var(--global-font-line-height);
99 | }
100 | ```
101 | This approach is deliberately conservative to provide a backwards-compatible starting point. Custom properties are quickly becoming a standard feature on the web, and developers are encouraged to use them with scoping when appropriate.
102 | ## Custom Media
103 | CSS custom properties can _not_ be used in media queries. For variables in media queries, the [Media Queries Level 5 specification introduces the `@custom-media` rule](https://drafts.csswg.org/mediaqueries-5/#custom-mq). This is bleeding-edge technology currently not supported by any browsers.
104 |
105 | [PostCSS Custom Media](https://github.com/postcss/postcss-custom-media) adds support for this upcoming feature, and WP Rig uses `@custom-media` with full backwards compatibility.
106 |
107 | The custom media declarations are in a CSS partial at `./assets/css/src/_custom-media.css`. Unlike custom properties, custom media references used in media queries in all CSS files are transformed by PostCSS into traditional media queries. This is done to prevent rule duplication. For developers this means you can safely use custom media in your themes and have WP Rig output functional CSS today as long as you declare the `@custom-media` rules in `./assets/css/src/_custom-media.css`.
108 |
109 | When custom media gains proper support in modern browsers, WP Rig will be updated to incorporate this feature without transformations.
110 | ### Nesting
111 | One popular feature of preprocessors like Sass and LESS is _nesting_, the ability to nest CSS rules inside one another for simpler cascade inheritance and less specificity. Thanks to the popularity of this feature, [CSS Nesting is now a level 1 module in the CSS spec](https://drafts.csswg.org/css-nesting-1/) meaning it will be implemented by modern browsers at some point in the not-too-distant future.
112 |
113 | [PostCSS Nesting](https://github.com/jonathantneal/postcss-nesting) adds support for this upcoming feature following the [CSS nesting specification](https://drafts.csswg.org/css-nesting-1/). WP Rig has PostCSS Nesting built in meaning you can use CSS nesting in your stylesheets today.
114 |
115 | The [CSS nesting specification](https://drafts.csswg.org/css-nesting-1/) has detailed information about how the feature works. The prototypical example is as follows:
116 |
117 | ```css
118 | a, b {
119 | color: red;
120 |
121 | & c, & d {
122 | color: white;
123 | }
124 | }
125 |
126 | /* becomes */
127 |
128 | a, b {
129 | color: red;
130 | }
131 |
132 | a c, a d, b c, b d {
133 | color: white;
134 | }
135 | ```
136 | Note: CSS nesting is experimental, but thanks to PostCSS Nesting it is safe to use in WP Rig themes because the output is pure CSS (without nesting).
137 | ## Why no Sass support?
138 | WP Rig 2.0 does not provide a build process for preprocessing SCSS ([Sass](https://sass-lang.com/)) files and partials. This is a deliberate decision in line with the overall philosophy of WP Rig: promote the latest best practices for progressive web content and optimization.
139 |
140 | Sass is to CSS what jQuery is to JavaScript: A tool to prototype simpler/better/different development techniques for relatively rigid languages. And just like modern JavaScript and ESNext has adopted and built on many features from jQuery rendering jQuery less relevant, so has modern CSS done the same with Sass.
141 | The WP Rig team decided to drop support for Sass because all major features of Sass are now available in CSS, with fallbacks, via PostCSS:
142 |
143 | Partials, imports, [custom properties (variables)](#custom-properties), [custom media](#custom-media), and [nesting](#nesting) are available to use in WP Rig via PostCSS. Advanced math is already part of the CSS spec thanks to `calc` and other operators.
144 |
145 | At present, the only major Sass features _not_ covered in WP Rig are _mixins_ and _extend/inherit_, this because they are presently not part of current or future CSS specifications. If you need these features, they can be added through PostCSS using [`postcss-mixins`](https://github.com/postcss/postcss-mixins) for mixins and either [`postcss-inherit`](https://github.com/GarthDB/postcss-inherit) or [`postcss-extend`](https://github.com/travco/postcss-extend) for extend/inherit. Including these features in WP Rig requires adding them as dev dependencies in `package.json` and altering the styles Gulp task in `./gulp/styles.js`.
146 | ## Progressive loading of CSS
147 | WP Rig employs progressive loading of CSS through [in-body tags](https://jakearchibald.com/2016/link-in-body/). Module-specific styles are held in module-specific stylesheets and loaded at module level. This is fundamentally different from how traditional WordPress themes handle CSS, and it has several advantages:
148 | - The main stylesheet file size is reduced.
149 | - Styles are only loaded if and when a module is present in the view.
150 | - Stylesheets are associated with their modules making them easier to work with.
151 | - Leverages HTTP/2 multiplexing and can be extended to include preloading, server push etc.
152 | - Module-level stylesheets are cached and can be individually updated without forcing reload of all styles on the site.
153 |
154 | As explained in [File structure and CSS modules](#file-structure-and-css-modules) above, only one stylesheet, `global.css` is always loaded by every template. All other stylesheets are loaded by their respective modules. This is done using the `wp_rig()->print_styles()` which takes a stylesheet handle as its parameter.
155 | As an example, `content.css` is loaded by [`index.php` at line 19](https://github.com/wprig/wprig/blob/v2.0/index.php#L19):
156 |
157 | ```php
158 | wp_rig()->print_styles( 'wp-rig-content' );
159 | ```
160 | Each individual stylesheet is registered in the `get_css_files()` function found in `./inc/Styles/Component.php` under the `$css_files` array:
161 |
162 | ```php
163 | $css_files = array(
164 | 'wp-rig-global' => array(
165 | 'file' => 'global.min.css',
166 | 'global' => true,
167 | ),
168 | 'wp-rig-comments' => array(
169 | 'file' => 'comments.min.css',
170 | 'preload_callback' => function() {
171 | return ! post_password_required() && is_singular() && ( comments_open() || get_comments_number() );
172 | },
173 | ),
174 | 'wp-rig-content' => array(
175 | 'file' => 'content.min.css',
176 | 'preload_callback' => '__return_true',
177 | ),
178 | 'wp-rig-sidebar' => array(
179 | 'file' => 'sidebar.min.css',
180 | 'preload_callback' => function() {
181 | return wp_rig()->is_primary_sidebar_active();
182 | },
183 | ),
184 | 'wp-rig-widgets' => array(
185 | 'file' => 'widgets.min.css',
186 | 'preload_callback' => function() {
187 | return wp_rig()->is_primary_sidebar_active();
188 | },
189 | ),
190 | 'wp-rig-front-page' => array(
191 | 'file' => 'front-page.min.css',
192 | 'preload_callback' => function() {
193 | global $template; return 'front-page.php' === basename( $template );
194 | },
195 | ),
196 | );
197 | ```
198 | Each entry in the `$css_files` array must follow the same convention:
199 | ```php
200 | ‘wp-rig-[label]’ => array(
201 | ‘file’ => ‘[filename].min.css’, // required
202 | ‘preload_callback’ => ‘[callback function or __return_true], // optional if file should be preloaded
203 | ‘global’ => true, // optional if file should be loaded in every template
204 | )
205 | ```
206 | The `preload_callback` value controls whether the stylesheet is preloaded in the `` section of the document. This improves performance in some circumstances, but counteracts the performance benefits of using [in-body tags](https://jakearchibald.com/2016/link-in-body/) because stylesheets are loaded _before_ they are used. For stylesheets that should _not_ be preloaded, use:
207 | ```php
208 | `'preload_callback' => '__return_false'`
209 | ```
210 | Tip: When preloading a stylesheet, use the console in Chrome developer tools to ensure no unnecessary stylesheets are loaded. A warning will appear letting you know if a stylesheet is preloaded but not used.
211 | Note: This approach has raised some questions and concerns around the use of `wp_print_styles` and how to handle custom CSS from the Customizer. For those interested in further reading, these issues, along with some extended research, was addressed by @kevinhoffman in a comment to [issue #277](https://github.com/wprig/wprig/issues/277#issuecomment-459809352).
212 | ## Code linting
213 | WP Rig provides CSS code linting to WordPress Coding Standards via [stylelint](https://stylelint.io/). Out of the box, this linting takes place during the build process and errors are referenced in the command line terminal.
214 | VS Code users can take full advantage of WP Rig’s stylelint configuration and get real-time coding assistance and format-on-save capability by enabling the [stylelint](https://marketplace.visualstudio.com/items?itemName=shinnn.stylelint) and [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) extensions and adding the following to Workspace Settings:
215 | ```json
216 | {
217 | "prettier.stylelintIntegration": true,
218 | "editor.formatOnSave": true
219 | }
220 | ```
221 | This assumes VS Code was opened into the `wp-content/themes/wprig` folder as the workspace.
222 |
--------------------------------------------------------------------------------
/documentation/php.md:
--------------------------------------------------------------------------------
1 | # PHP Architecture in WP Rig
2 |
3 | WP Rig changes the way WordPress themes are developed, not only on the client side, but also on the server side.
4 |
5 | Historically, the common WordPress theme's PHP codebase has consisted of random PHP functions, scattered across different files, without too many architectural thoughts behind it. And while it is debatable whether themes should even have to contain as much server-side functionality as they do and not only focus on HTML, CSS and JavaScript (which the Gutenberg project might fix in the long run), the current state is that this is simply required.
6 |
7 | WP Rig introduces several new patterns in how theme PHP code is structured and executed. These are not just for the sake of changing things, they solve actual problems. In other areas where a change wouldn't be more than of cosmetic nature, WP Rig stays as close as possible to the way themes have been developed in the past: As an example for that, WP Rig still uses a directory `inc` for its PHP functionality although nowadays it's more common to have this called `src` or similar - but changing that wouldn't solve a real problem, it would just be one more (in this case, admittedly simple) thing to get used to.
8 |
9 | This article will first outline the goals of the WP Rig architecture and the problems it solves. It will then go into more detail what the architecture and API actually looks like and how to work with it. If you don't care about the background and just want to quickly start modifying and extending WP Rig's PHP code for your theme, you can skip the first section - although reading that may give you a better understanding and possibly provide you with ideas for other non-WP Rig WordPress projects as well.
10 |
11 | ## Goals of the WP Rig Architecture
12 |
13 | ### Clear Definition of Public API
14 |
15 | WP Rig moves away from the function paradigm and organizes its code entirely in classes. Contrary to functions, which are always publicly available, class methods (i.e. "functions in classes") can have different visibility levels, for example to prevent calling a method from the outside of the class.
16 |
17 | Most functions that themes include are internal to the theme, so they should not be exposed to the outside. Sure, if you have followed theme development for a while, you probably just know that you should not call a function like `mytheme_setup()` manually ever - as the theme already hooks it into `after_setup_theme`, thus has it be called automatically by WordPress. And its code is written in a way the function should definitely not be called again in the same request. However, this requires documentation and developers to know that. Nothing in the code restricts a developer from calling the function at any random point.
18 |
19 | One might argue that calling this a problem is a bit overkill - but, to use another example, precisely the lack of proper definition of public vs private APIs causes WordPress core (which similar to themes mostly consists of public functions) to be so problematic with backward-compatibility. Almost every change that happens in WordPress core is in some way a breaking change. What is not considered a breaking change is probably so only because of the (in most cases true) assumption that nobody uses the respective function that's being changed in unexpected ways. In many other cases though, bug fixes get lost after endless discussions about things like "we probably should not fix this function, as someone might be using it in that way although it should not be used at all" - which brings us back here. One goal of WP Rig is have the code itself define that something is public or not public (of course still including actual documentation, like what you are reading now :) ).
20 |
21 | ### Separation of Concerns
22 |
23 | WP Rig's classes are organized into so-called components. A component is responsible for a distinct feature of the theme. That can be an obvious feature literally like for example support for WordPress core's "Custom Header", but it can also be a feature in the more broad sense, such as the theme being fully compatible with "AMP" or the theme's focus on "accessibility" by providing a suite of generic accessibility fixes that WordPress itself does not include. Each of these components has a single main class, but can consist of as many classes as needed (although, at the point of writing, every component has in fact only the one main class). The components are then organized in different directories.
24 |
25 | WordPress themes have historically done an okay-ish job of separating concerns. Aside from the terrible "you can dump this in your `functions.php`" approach, there are usually different files that contain the functions, often called for example `inc/template-tags.php` for functions that the template files need to use, or `inc/customize.php` for Customizer integration. However, as mentioned there is still use of the generic `functions.php` file, and even some functions themselves take care of multiple things that belong to different features. An example for that is the typical `mytheme_setup()` function that adds theme support for pretty much anything that theme support can be added for. That approach makes sense for one-off features, like `automatic-feed-links` or `title-tag`, things that every theme just needs to support and that are nothing more than a flag to enable. However, mixing in support for things like `custom-header`, `custom-background` or `editor-color-palette` is questionable, as each of these is a separate non-trivial feature with arguments (or at least is related to a separate feature like the editor). In the case of `custom-header`, adding theme support possibly even relies on other functions that need to be part of the theme.
26 |
27 | Separating concerns helps keeping your codebase organized. This in turn helps navigating the codebase. Especially with WP Rig being a starter theme, it should be easy to find out which piece of code to navigate to when wanting to adjust a particular feature. For example, you might want to render the `custom-header` feature in a different way in your theme. Or you might not even want to support the `custom-header` feature at all. When looking at the historically used code organization of a WordPress theme, you'd never be able to find out where the code for that part was located. Of course, if you are a seasoned theme developer, you'd guess that it is in `functions.php`, but let's be honest, that's cheating because you already have made that experience often enough. In WP Rig, you instead have a "Custom Header" component, and thus also directory called `Custom_Header`, so it is obvious where to navigate. In fact, if you didn't want to support that feature, all you would have to do is delete the directory and remove [its instantiation in the `Theme` class](https://github.com/wprig/wprig/blob/v2.0/inc/Theme.php#L149) (more on the latter in the next section).
28 |
29 | Another example that highlights the organization of the codebase is that WP Rig has a "Styles" component, but not a "Scripts" component. "Styles" is its own component since the theme's CSS files, while being granular, are not granular enough to apply per feature, as that would end up causing way too many CSS files to be present. Furthermore, CSS files in WP Rig are loaded in a special way to help performance, requiring extra PHP logic that makes the existence of a distinct "Styles" component more viable. JavaScript files however always exist to support one specific feature. For example there is the `navigation.js` script that makes the navigation menu more accessible - as such, it is part of the "Accessibility" component. Or there is the `lazyload.js` script taking care of lazy loading, making it part of the "Lazyload" component. Instead of dumping all `wp_enqueue_script()` calls of those scripts into one file, together with all the `wp_enqueue_style()` calls, JavaScript is loaded from the component that it is used for. This is precisely what the separation of concerns is about, organizing the codebase by its features, not by the WordPress functions it calls.
30 |
31 | ### Separating Invocation from Definition
32 |
33 | Each of WP Rig's component main classes has an `initialize()` method that adds the necessary actions and filters. That means that the hooks are not automatically added just by including the file that the hook callback methods are part of - the theme explicitly needs to call the `initialize()` method. You might now ask "Why would I want to write extra code instead to call that method?" The reason is testability.
34 |
35 | Preferably every piece of code in a project should be covered by tests that verify it works as expected. [WP Rig provides both unit and integration tests](https://github.com/wprig/wprig/tree/v2.0/tests/phpunit) to ensure that and to prevent unnoticed regressions. Particularly for unit tests, it is important that each unit (for example a PHP function or method) is tested in isolation without needing to consider side effects. By automatically having code executed on load of the same files that contain that code, this becomes impossible. In other words, invoking a function or method should not happen in the same location that also declares that function or method. In addition, the `initialize()` method of each component bundling all related `add_action()` and `add_filter()` calls ensures that there is a single entry point to hook in that component, i.e. integrate it with WordPress.
36 |
37 | Don't worry, you still don't actually need to manually call the `initialize()` method of each component. Since each component must implement a specific interface (more on that later), the theme knows that each component has such an `initialize()` method and will invoke it automatically. As a matter of fact, [the `Theme` class has its own `initialize()` method](https://github.com/wprig/wprig/blob/v2.0/inc/Theme.php#L83) which calls the `initialize()` methods of all components. As such, this method is the single canonical entry point to the entire theme, integrating all theme components with WordPress.
38 |
39 | ## How to Work with the WP Rig Architecture
40 |
41 | Before actually diving into the architecture, let's highlight that WP Rig uses [PHP namespaces](http://php.net/manual/en/language.namespaces.php) for its codebase. It also relies on [autoloading](http://php.net/manual/en/language.oop5.autoload.php), so every file containing a [class](http://php.net/manual/en/language.oop5.php), [interface](http://php.net/manual/en/language.oop5.interfaces.php) or [trait](http://php.net/manual/en/language.oop5.traits.php) should only contain that structure and nothing else. Such files should not be loaded anywhere manually, you can just rely on the autoloader. The root namespace for all code is `WP_Rig\WP_Rig` (remember that your own namespace will only be applied to your code when building the theme for production), and all code in that namespace (except tests) is located in the `inc` directory. From there on, sub-namespaces map to subdirectory names, and the class name itself must match the file name (followed by the `.php` extension of course), following the [PSR-4 standard](https://www.php-fig.org/psr/psr-4/). Make sure to follow these conventions for all files you might add to your theme based on WP Rig.
42 |
43 | Something else to be aware of is that WP Rig uses function and method [parameter type hints](http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration) and [return type hints](http://php.net/manual/en/functions.returning-values.php#functions.returning-values.type-declaration) wherever possible. Since the theme requires PHP 7.0 as minimum version, it can use these features, and they are a simple means to make your code more error-proof.
44 |
45 | ### Working with Components
46 |
47 | As mentioned earlier, the different PHP features of WP Rig are organized in so-called components. Whether you plan to adjust existing theme behavior or add an entirely new feature to the theme, you will work with components. For the sake of this guide, we will implement our own component while explaining how things work. Particularly, we will add a component that allows a user of the theme to toggle a Customizer setting to decide whether the theme's archive views should display excerpts (using `the_excerpt()`) or regular shortened content using the `` tag (using `the_content()`). Maybe you even want to use this in your theme - the reason WP Rig does not include something like this is that it would still be too opinionated. WP Rig should be a starter theme and not get bloated by too many features people _might_ use (but likely more often would need to remove). But now, let's write our own component!
48 |
49 | #### Scaffolding the Component Class
50 |
51 | Every component has its own directory in `inc`, with the directory name matching the sub-namespace part, as explained in the previous paragraph. Let's call our component "Archive_Content". Based on that, the directory name must be `Archive_Content` and the namespace must be `WP_Rig\WP_Rig\Archive_Content`. Every component must have at least one class, the so-called component main class. That class should simply be called `Component` (note that the class name will still be unique because of the namespace, making the fully qualified class name to be something like `WP_Rig\WP_Rig\Archive_Content\Component`). The class must implement the [`WP_Rig\WP_Rig\Component_Interface` interface](https://github.com/wprig/wprig/blob/v2.0/inc/Component_Interface.php), thus you must at least implement the methods `get_slug()` and `initialize()`. Here is what this file could look like:
52 |
53 | ```php
54 | add_setting(
139 | 'archives_use_excerpt',
140 | array(
141 | 'default' => false,
142 | 'sanitize_callback' => 'rest_sanitize_boolean',
143 | )
144 | );
145 |
146 | // Register the Customizer control for the setting, using a checkbox.
147 | $wp_customize->add_control(
148 | 'archives_use_excerpt',
149 | array(
150 | 'label' => __( 'Use excerpts in archive views?', 'wp-rig' ),
151 | 'section' => 'theme_options',
152 | 'type' => 'checkbox',
153 | )
154 | );
155 | }
156 | }
157 |
158 | ```
159 |
160 | Most of the newly added code should be familiar code if you have worked with the Customizer before. Similar as in the previous version of the code, note the new `use ...` statements. This time we import the `WP_Customize_Manager` class from WordPress core that is used here, plus several core functions. Contrary to classes, including statements for the functions is _not_ necessary here since namespaces will by default fall back to the global namespace (of which all WordPress core functions are a part of). However having these `use ...` statements in the file once again helps to quickly be able to tell which outside functions the file depends on.
161 |
162 | With the above code, you already have the Customizer integration in place, and its value will be stored in a theme mod, so you can retrieve it with the WordPress function `get_theme_mod( 'archives_use_excerpt' )`. So now you can go into the [respective template file that displays post content](https://github.com/wprig/wprig/blob/v2.0/template-parts/content/entry_content.php) and adjust it as follows:
163 |
164 | ```php
165 |
174 |
175 |
176 |
187 |
188 |
189 | ```
190 |
191 | However, it would be much nicer to have a dedicated function to call for this, for example something like `using_archive_excerpts()`, that you can use from your template. We could of course just introduce a function for that and place it somewhere. However, that would go against our separation of concerns since it clearly belongs to our "Archive_Content" component. So let's look into how we can expose specific methods in our component to the outside.
192 |
193 | #### Exposing Template Tags
194 |
195 | WordPress typically calls functions that should be used from the template files of your theme "template tags". And there's no reason to change that naming convention. Historically, you would have put these as functions in a file called `template-functions.php` or `template-tags.php`. In WP Rig however, you can place them as methods alongside the rest of the code they actually integrate with, as part of the feature they are actually part of. While none of the component methods are exposed to the outside of the class by default, WP Rig contains a mechanism to work around that specifically for that purpose.
196 |
197 | You might remember that each component has to implement the `WP_Rig\WP_Rig\Component_Interface` interface. A great thing about interfaces contrary is that it is possible for a class to implement multiple interfaces, contrary to abstract classes where a child can only extend a single parent class. WP Rig includes a `WP_Rig\WP_Rig\Templating_Component_Interface` interface, which is not mandatory to implement for each component, but only for those components that contain at least one method that should be exposed to the outside to be used in template files (again, these are called "template tags"). When a component main class implements this interface, it needs to include a method `template_tags()` which returns an associative array of `$template_tag_name => $template_tag_callback` pairs. The `$template_tag_callback` is the actual callback, which you should typically include as a public method on the class. The `$template_tag_name` is the name under which that template tag should globally be callable. This can in theory be different from the callback name, but it is recommended to keep the name consistent with the callback method, just for code readability. Any template tag made available like that can then be called via `wp_rig()->{$template_tag_name}()` - for example, for our component and the previously suggested name for the template tag we would use `wp_rig()->using_archive_excerpts()`. Internally, aggregating these template tags and exposing them via the `wp_rig()` function is handled by [the internal `WP_Rig\WP_Rig\Template_Tags` class](https://github.com/wprig/wprig/blob/v2.0/inc/Template_Tags.php), in combination with [`WP_Rig\WP_Rig\Theme`](https://github.com/wprig/wprig/blob/v2.0/inc/Theme.php). You don't necessarily need to worry about how this works - if you're interested, feel free to check out the code of the two classes and the `wp_rig()` function in more detail. Here is the full code for our component including exposure of the template tag:
198 |
199 | ```php
200 | using_archive_excerpts()`
221 | */
222 | class Component implements Component_Interface, Templating_Component_Interface {
223 |
224 | /**
225 | * Gets the unique identifier for the theme component.
226 | *
227 | * @return string Component slug.
228 | */
229 | public function get_slug() : string {
230 | return 'archive_content';
231 | }
232 |
233 | /**
234 | * Adds the action and filter hooks to integrate with WordPress.
235 | */
236 | public function initialize() {
237 | add_action( 'customize_register', array( $this, 'action_register_customizer_control' ) );
238 | }
239 |
240 | /**
241 | * Gets template tags to expose as methods on the Template_Tags class instance, accessible through `wp_rig()`.
242 | *
243 | * @return array Associative array of $method_name => $callback_info pairs. Each $callback_info must either be
244 | * a callable or an array with key 'callable'. This approach is used to reserve the possibility of
245 | * adding support for further arguments in the future.
246 | */
247 | public function template_tags() : array {
248 | return array(
249 | 'using_archive_excerpts' => array( $this, 'using_archive_excerpts' ),
250 | );
251 | }
252 |
253 | /**
254 | * Adds a Customizer setting and control for toggling usage of `the_content()` or `the_excerpt()` in archives.
255 | *
256 | * @param WP_Customize_Manager $wp_customize Customizer manager instance.
257 | */
258 | public function action_register_customizer_control( WP_Customize_Manager $wp_customize ) {
259 | // Register the Customizer setting and ensure its value is a boolean.
260 | $wp_customize->add_setting(
261 | 'archives_use_excerpt',
262 | array(
263 | 'default' => false,
264 | 'sanitize_callback' => 'rest_sanitize_boolean',
265 | )
266 | );
267 |
268 | // Register the Customizer control for the setting, using a checkbox.
269 | $wp_customize->add_control(
270 | 'archives_use_excerpt',
271 | array(
272 | 'label' => __( 'Use excerpts in archive views?', 'wp-rig' ),
273 | 'section' => 'theme_options',
274 | 'type' => 'checkbox',
275 | )
276 | );
277 | }
278 |
279 | /**
280 | * Determines whether archives should use excerpts instead of regular post content.
281 | *
282 | * @return bool Whether to use excerpts in archives.
283 | */
284 | public function using_archive_excerpts() : bool {
285 | return (bool) get_theme_mod( 'archives_use_excerpt' );
286 | }
287 | }
288 |
289 | ```
290 |
291 | As you can see, a new `using_archive_excerpts()` method is added and then exported to the outside via the new `template_tags()` method that is added in combination with implementing `WP_Rig\WP_Rig\Templating_Component_Interface`. A good idea related to that is to document the available template tags in the source code, as seen in the doc block for the component class. Again, take note of how the additional dependencies (the interface and WordPress's `get_theme_mod()` function) have been added as `use ...` statements.
292 |
293 | We now have the component class completed. Let's open [the post content template file](https://github.com/wprig/wprig/blob/v2.0/template-parts/content/entry_content.php) again and replace our previously used if condition with `! is_singular( get_post_type() ) && wp_rig()->using_archive_excerpts()`. What remains is that we need to make the theme aware of it.
294 |
295 | #### Registering the Component Class
296 |
297 | Making the theme use our new component class is very straightforward. Simply navigate to the [`WP_Rig\WP_Rig\Theme::get_default_components()` method](https://github.com/wprig/wprig/blob/v2.0/inc/Theme.php#L136) and add the new component in there. Note that the order of the components there matters in some cases, for example if similar hooks use a similar priority. Generally, a good approach to follow is to add more foundational components towards the top and more pluggable components or components that might even rely on other components towards the bottom of the list. For our case, let's append `WP_Rig\WP_Rig\Archive_Content\Component` to the end of the array. Note that since the class itself is in the `WP_Rig\WP_Rig` namespace, we can refer to our class relatively from that namespace, via `Archive_Content\Component`. Adding our component to the list is all we needed to do for the theme to handle it. It will call its `initialize()` method automatically now.
298 |
299 | And that's it for our component! It might have been a bit of work getting this rather simple enhancement done and understanding how all the different parts connect. Once you become more familiar over time though, the architectural patterns used in WP Rig should boost your productivity significantly.
300 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------