Skip to content

Latest commit

 

History

History
279 lines (202 loc) · 11.4 KB

CONTRIBUTING.md

File metadata and controls

279 lines (202 loc) · 11.4 KB

Contributing to Timber

Hey there! We’re really happy you’ve found your way here 💪. Timber is a community project that is developed by people from all over the world. We appreciate any help.

Here are ways to get involved:

  1. Star the project!
  2. Answer questions that come in through GitHub issues.
  3. Report a bug that you find.
  4. Share a theme you’ve built with Timber. This helps transfer knowledge about best practices, etc. Add it to the Showcase list.
  5. Tweet and blog about the advantages (and criticisms) of the project and Twig.
  6. Browse "help wanted" and "good first issue" labels for areas of WordPress/PHP/code you know well to consider, build or document.
  7. Answer questions on Stack Overflow posted under the «Timber» tag. You can also subscribe to a tag via email to get notified when someone needs help.
  8. Answer questions in the support channel on Gitter.

Table of Contents

Pull Requests

Pull requests are highly appreciated. More than 150 people have written parts of Timber (so far). Here are some guidelines to help:

  1. Solve a problem – Features are great, but even better is cleaning-up and fixing issues in the code that you discover.
  2. Write tests – This helps preserve functionality as the codebase grows and demonstrates how your change affects the code.
  3. Write documentation – Timber is only useful if its features are documented. This covers inline documentation of the code as well as documenting functionality and use cases in the Guides section of the documentation.
  4. Small > big – Better to have a few small pull requests that address specific parts of the code, than one big pull request that jumps all over.
  5. Comply with Coding Standards – See next section.

Coding Standards

We try to follow the WordPress Coding Standards as close as we can, with the following exceptions:

  • Class and file names are defined in StudlyCaps. We follow the PSR-0 standard, because we use autoloading via Composer.
  • We use hook names namespaced by / instead of underscores (e.g. timber/context instead of timber_context).

Use PHP_CodeSniffer to detect coding standard violations

To check where the code deviates from the standards, you can use PHP_CodeSniffer. Timber comes with a phpcs.xml in the root folder of the repository, so that the the Timber code base will be automatically checked for coding standards violations.

Command Line Usage

When you run composer install in Timber’s repository root, you will get all required dependencies to check the coding standards.

To run PHP_CodeSniffer with the default settings on all relevant Timber files, use the following command from the root folder of the Timber repository:

composer lint

You can check a single file like this:

./vendor/bin/phpcs ./lib/Menu.php

Use ./vendor/bin/phpcs --help for a list of available settings or refer to the PHP_CodeSniffer documentation.

Use it in your IDE

Please refer to https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards#using-phpcs-and-wpcs-from-within-your-ide for different ways to use PHP_CodeSniffer directly in your IDE. In some IDEs like PHPStorm, you may have to select the phpcs.xml explicitly to apply the proper standards.

Whitelisting

If it’s not possible to adapt to certain rules, code could be whitelisted. However, this should be used sparingly.

Inline Documentation

The Reference section of the documentation is automatically generated from the inline documentation of the Timber code base. To document Timber, we follow the official PHP Documentation Standards of WordPress.

There are minor differences to the official standards:

  • For class headers, we don’t use @package or @subpackage tags.
  • We don’t use the @access tag.

Ignoring Structural Elements

The documentation generator ignores a number of elements. An element (class, method, property) is ignored when one of the following conditions applies:

  • No DocBlock is provided
  • No @api tag is present
  • An @ignore tag is present
  • An @internal tag is present
  • The visibility is private (applies to methods only)

This means that for Markdown files to be generated for a class at all, you’ll need at least a DocBlock with an @api tag.

Referencing class names

When referencing a namespaced class name in a type (for example in a @param or @return tag), then use the fully qualified name. Example: Timber\Post instead of just Post.

Code examples

Timber uses tabs for indentation, but you should always use spaces for indentation in code examples, because the resulting Markdown will have a more consistens styling.

The @example tag allows you add code examples to your DocBlocks, including fenced code blocks:

/**
 * Function summary.
 * 
 * Function description.
 *
 * @api
 * @example
 *
 * Optional text to describe the example.
 * 
 * ```php
 * my_method( 'example', false );
 * ```
 *
 * @param string $param1 Description. Default 'value'.
 * @param bool   $param2 Optional. Description. Default true.
 */
function my_method( $param1, $param2 = true ) {}

Reference linking with @see tag

When you use the @see tag, the Reference Generator will automatically convert it to a link to the reference.

  • Use this tag only when the referenced method has an @api tag, which means that it is public.
  • Beware, you’ll always use the notation with ::, which you normally know from static methods. But even if the method that you link is not static, you’ll have to use the double colon.

An example:

@see \Timber\Image::src()

will turn into this:

<strong>see</strong>
<a href="/docs/reference/timber-image/#src">Timber\Image::src()</a>

Documenting Hooks

Follow the official Inline Documentation Standards for Actions and Filters to document hooks.

Keywords for filters and actions

A DocBlock that documents a hook should always start with the keyword

  • Filters for filter hooks
  • Fires for action hooks

This is needed so that the Hook Reference Generator can detect the comments associated with filters and actions.

Syntax

/**
 * Filters … / Fires … (Summary)
 *
 * Description.
 *
 * `$var` Optional description of variables that might be used in the filter name.
 * 
 * @see \Timber\Classname::function()
 * @link https://github.com/timber/timber/pull/1254
 * @since x.x.x
 * @deprecated x.x.x
 * @example
 * Optional text to describe the example.
 * 
 * ```php
 * // A PHP example
 *
 * /**
 *  * Multiline comments are possible as well.
 *  * You’ll need to escape the closing tag with a "\".
 *  *\/
 * ```
 *
 * ```twig
 * {# A Twig example #}
 * ```
 *
 * @param type  $var Description. Default 'value'.
 * @param array $args {
 *     Short description about this hash.
 *
 *     @type type $var Optional. Description. Default value.
 *     @type type $var Optional. Description. Default value.
 * }
 * @param type  $var Optional. Description. Default value.
 */

Dynamic filters

When a filter contains a variable, it should be marked up with double quotes " and the variable name inside curly braces:

$force = apply_filters( "timber/transient/force_transient_{$slug}", $force );

Additionally to this, document what the variable is by adding it to the description. Add it on a new line with the variable wrapped in backticks, so that it appears as code in Markdown:

/**
 * Filters the status of a particularly named transient.
 *
 * Allows you to override the behavior on a case-by-case basis.  
 * `$slug` The transient slug.
 *
 * @param bool $force Param description.
 */
$force = apply_filters( "timber/transient/force_transient_{$slug}", $force );

Multiline declaration

Formatting a filter into multiple lines when the line should be too long is allowed:

/**
 * Filters …
 */
$force = apply_filters_deprecated(
    'timber_force_transients',
    array( $force ),
    '2.0.0',
    'timber/transient/force_transients'
);

Unfinished filters

If a filter description is not finished yet, mark it up with the @todo tag. It’s okay if you don’t know what a filter is doing exactly or if you’re unsure about what a parameter does. Describe what needs to be done in the @todo tag.

/**
 * Filters …
 *
 * @todo Add summary, add description.
 *
 * @param bool $force Param description.
 */

As soon as the todo is resolved, the @todo tag can be removed.

Process

All PRs receive a review from at least one maintainer. We’ll do our best to do that review in a week, but we’d rather go slow and get it right than merge in code with issues that just lead to trouble.

GitHub reviews & assignments

You might see us assign multiple reviewers, in this case these are OR checks (i.e. either Coby or Pascal) unless we explicitly say it’s an AND type thing (i.e. can both Lukas and Maciej check this out?).

We use the assignee to show who’s responsible at that moment. We’ll assign back to the submitter if we need additional info/code/response, or it might be assigned to a branch maintainer if it needs more thought/revision (perhaps it’s directly related to an issue that's actively being worked on).

Once approved, the lead maintainer for the branch should merge the PR into the master or 2.x branch. The 1.x team will work to resolve merge conflicts on #1617 (2.x into master) so the branches stay in sync.

Branch Maintainers

  • 1.x: @jaredNova (lead), @palmiak
  • 2.x: @gchtr (lead), @pascalknecht, @cobytamayo