### Run the documentation site locally Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/README.md Use these commands to install dependencies and start the Jekyll development server for the documentation project. ```bash bundle install bundle exec jekyll serve ``` -------------------------------- ### Third-Party Integration Documentation Example Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Design.md An example of how to document third-party integrations in an `INTEGRATIONS.md` file, including service details, scheduling, and integration points. ```markdown ## CrunchBase Remote service for fetching funding and other investment data related to tech startups. ### Scheduling - The CrunchBase API is used via JS in a dynamic product/company search on post edit pages - Funding data is pulled every 6 hours by WP Cron to update cached data ### Integration Points - /assets/js/src/crunchbase-autocomplete.js - /includes/classes/crunchbase.php - /includes/classes/cron.php ### Development API - See https://somesitethatrequireslogin.com/credentials-for-project ``` -------------------------------- ### Heredoc Syntax Example Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/PHP.md Demonstrates the heredoc syntax for constructing multi-line strings. ```php $y = <<then stop moving it like that!" JOKE; ``` -------------------------------- ### Class-based Module Instantiation Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/JavaScript.md Example of initializing an ES6 class module with configuration options. ```javascript import Module from './mymodule'; /* Module is an ES6 class */ new Module('.element-selector', { /* options */ onEvent1: () => {}, onEvent2: () => {}, }); ``` -------------------------------- ### Recommended PHP Packages for WordPress Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Systems.md These packages are commonly recommended for WordPress installations to ensure compatibility and performance. Not all may be necessary for every setup. ```php php-cli php-common php-fpm php-gd php-mbstring php-mcrypt php-mysqlnd php-opcache php-pdo php-pear php-pecl-jsonc php-pecl-memcache php-pecl-memcached php-pecl-redis php-pecl-zip php-process php-redis php-soap php-xml ``` -------------------------------- ### Composer JSON Configuration Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Design.md Example `composer.json` file for a WordPress project, specifying dependencies and repository configurations. ```json { "name": "10up/project-slug", "description": "Project description", "repositories":[ { "type":"composer", "url":"https://wpackagist.org" } ], "extra": { "wordpress-install-dir": "wp" }, "require": { "johnpbloch/wordpress": "4.9", "wpackagist-plugin/wordpress-importer": "dev-trunk", "wpackagist-plugin/debug-bar": "dev-trunk", "wpackagist-plugin/debug-bar-extender": "dev-trunk" } } ``` -------------------------------- ### Named Export Example Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/JavaScript.md Demonstrates how to create a named export in JavaScript. This allows other modules to import the specific exported item. ```javascript export const example = 66; ``` -------------------------------- ### Serve fonts locally with @font-face Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Performance.md Uses the local() function to prioritize fonts already installed on the user's system for faster rendering. ```css @font-face { font-family: 'WebFont'; font-display: swap; src: local('myfont.woff2'), url('myfont.woff2') format('woff2'), url('myfont.woff') format('woff'); } ``` -------------------------------- ### Composer Project Structure Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Design.md Defines the directory structure for a Composer-based WordPress project, including dependency management and WordPress core installation. ```text |- composer.json ____________________________ # Define third party dependencies |- wp-config.php ____________________________ # WordPress configuration |- wp/ ______________________________________ # Composer install WordPress here |- wp-content/ ______________________________ # Composer dependencies | |- themes/ _______________________________ # Themes directory | |- custom-theme/ _______________________ # Custom theme | |- plugins/ ______________________________ # Plugins directory | |- custom-plugin/ ______________________ # Custom plugin ``` -------------------------------- ### Project Directory Structure Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Design.md The base file structure for all themes and plugins. ```text |- assets/ | |- css/ _______________________________ # See below for details | |- fonts/ _____________________________ # Custom/hosted fonts | |- images/ ____________________________ # Theme images | |- js/ ________________________________ # See below for details | |- svg/ _______________________________ # Vector images that will be processed into icons |- bin/ __________________________________ # WP-CLI and other scripts |- gulp-tasks/ ___________________________ # Individual Gulp tasks |- includes/ _____________________________ # PHP classes and files | |- classes/ _________________________ # PHP classes |- languages/ ____________________________ # Translations |- node_modules/ _________________________ # npm modules |- partials/ _____________________________ # Template parts |- templates/ ____________________________ # Page templates |- tests/ | |- php/ _______________________________ # PHP testing suite | |- js/ ________________________________ # JavaScript testing suite |- vendor/ _______________________________ # Composer dependencies |- .babelrc ______________________________ # Babel config settings |- .editorconfig _________________________ # Editor config settings |- .eslintrc _____________________________ # ESLint config settings |- composer.json _________________________ # Composer package file |- gulpfile.babel.js _____________________ # Gulp config settings |- package.json __________________________ # npm package file |- webpack.config.babel.js _______________ # Webpack config settings ``` -------------------------------- ### Prepare and execute a raw SQL query Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/PHP.md Uses $wpdb->prepare() to sanitize inputs and force integer types for secure database retrieval. ```php get_results( $wpdb->prepare( "SELECT id, name FROM $wpdb->posts WHERE ID='%d'", absint( $post_id ) ) ); ?> ``` -------------------------------- ### Build Mobile-First Responsive Layouts Source: https://context7.com/10up/engineering-best-practices/llms.txt Utilize modern CSS features like clamp(), CSS Grid, and Flexbox to create fluid, responsive designs with minimal media query usage. ```css /* Mobile-first base styles */ .container { width: 100%; max-width: 75rem; margin-inline: auto; padding-inline: var(--spacing-md); } /* Fluid typography using clamp() - no media queries needed */ .hero-title { font-size: clamp(2rem, 5vw + 1rem, 4rem); line-height: 1.1; } .body-text { font-size: clamp(1rem, 0.5vw + 0.875rem, 1.25rem); } /* Intrinsic layouts with CSS Grid - adapts without media queries */ .auto-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); gap: var(--spacing-lg); } /* Flexbox with wrapping for natural responsive behavior */ .nav-list { display: flex; flex-wrap: wrap; gap: var(--spacing-sm); list-style: none; padding: 0; margin: 0; } /* Use media queries as enhancement, not foundation */ .sidebar-layout { display: grid; gap: var(--spacing-lg); } @media (min-width: 48rem) { .sidebar-layout { grid-template-columns: 1fr 300px; } } /* Support 400% zoom - use relative units */ .header { padding-block: var(--spacing-md); } /* Sticky headers shouldn't dominate at high zoom */ @media (min-height: 30rem) { .header--sticky { position: sticky; top: 0; } } ``` -------------------------------- ### Serve Responsive Images with srcset and sizes Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Performance.md Use the `srcset` and `sizes` attributes on `` tags to serve appropriately sized images based on the viewport and device resolution. This improves performance by reducing bandwidth usage. ```html 10up.com Logo ``` -------------------------------- ### API Key Management with WordPress Filters Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Design.md PHP code demonstrating how to define API keys using constants, defaulting to development credentials and respecting the `WP_ENVIRONMENT_TYPE`. ```php ``` -------------------------------- ### Documenting WordPress Hooks and Functions Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/PHP.md Use verbose docblocks to explain the purpose and logic of functions. Ensure hooks are documented with clear descriptions of parameters and return values. ```php ``` -------------------------------- ### Optimize Images with Responsive srcset and Lazy Loading Source: https://context7.com/10up/engineering-best-practices/llms.txt Use `srcset` and `sizes` for responsive images, `loading="eager"` for LCP images with `fetchpriority="high"`, and `loading="lazy"` for below-the-fold images. Supports modern formats like WebP with fallbacks. ```html Hero banner showing product showcase Product thumbnail Descriptive alt text ``` -------------------------------- ### Validate Email Output with sanitize_email() Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/PHP.md Use sanitize_email() to ensure output is a valid email address. This is an example of data validation, offering stricter control than a general escaping function like esc_attr(). ```php Email me ``` -------------------------------- ### PHP Class with Docblock and Constructor Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/PHP.md Define a well-documented PHP class with a leading docblock explaining its purpose and documenting each method and property. The constructor should handle initialization and potential exceptions. ```php _post = get_post( $post ); } } ``` -------------------------------- ### Disable File Modifications in WordPress Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Systems.md Use this constant in wp-config.php to prevent code installations or modifications through the WordPress admin area. This enhances security and prevents confusion when using external deployment processes. ```php define('DISALLOW_FILE_MODS', true); ``` -------------------------------- ### Register Assets with Versioning Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/PHP.md Use a constant to manage asset versions for cache busting when registering scripts. ```php ``` -------------------------------- ### JavaScript Directory Structure Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Design.md Detailed breakdown of the assets/js directory. ```text |- assets/js/ | |- admin/ ___________________________ # JS for the admin | |- frontend/ ________________________ # JS for the front end | |- components/ ___________________ # Component-level JS | |- shared/ __________________________ # Shared JS between the admin and front end ``` -------------------------------- ### Organize PHP Code with Namespacing Source: https://context7.com/10up/engineering-best-practices/llms.txt Use namespaces and import declarations to prevent naming collisions in non-template PHP files. ```php true, 'label' => __( 'Projects', 'client-theme' ), ) ); } /** * Enqueue theme assets. */ function enqueue_assets() { // Using imported class - cleaner than full namespace path $twitter_api = new TwitterAPI(); wp_enqueue_script( 'theme-scripts', get_template_directory_uri() . '/js/scripts.js', array(), THEME_VERSION, true ); } bootstrap(); ?> ``` -------------------------------- ### Set X-Frame-Options Header Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Site-Security.md Configure the X-Frame-Options HTTP header to SAMEORIGIN to protect against clickjacking attacks. This restricts the site from being embedded in frames on other domains. ```text X-Frame-Options: SAMEORIGIN ``` -------------------------------- ### Create a UserProvider with React Context Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/React.md Implements a provider component that fetches user data and exposes it via a custom hook. ```javascript import React, { useEffect, useState, useContext, createContext } from 'react'; import PropTypes from 'prop-types'; import { fetchUser } from '../util'; export const UserContext = createContext(); export const useUser = () => { const data = useContext(UserContext); return data.user ? data.user : null; }; const UserProvider = ({ children }) => { const [user, setUser] = useState(null); useEffect(() => { fetchUser().then(setUser); }, []); return {children}; }; UserProvider.propTypes = { children: PropTypes.oneOfType([PropTypes.element, PropTypes.arrayOf(PropTypes.element)]) .isRequired, }; export default UserProvider; ``` -------------------------------- ### Check Theme Support Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/PHP.md Verify if the active theme supports a specific feature before executing plugin-specific code. ```php {}); module1.addEventListener('onEvent2', () => {}); module1.doSomething(); module1.hide(); ``` ```javascript // Option 2: not using classes import module from './mymodule'; module('.element-selector', { /* options */ }); ``` -------------------------------- ### Demonstrate Global Namespace Pollution Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/JavaScript.md Shows how variables and properties defined in the global scope are automatically attached to the window object. ```javascript console.log(this === window); // true for (var i = 0; i < 9; i++) { // Do stuff } const result = true; console.log(window.result === result); // true console.log(window.i === i); // true ``` -------------------------------- ### Define Foundational List Styles Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/CSS.md Apply default styling to list elements using :where() to maintain low specificity for easier overrides. ```css :where(ul, ol, dl) { /* styles here */ } ``` -------------------------------- ### Tag a release version Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Version-Control.md Command to create an annotated tag for a new release version in the trunk branch. ```sh git tag -a -m "Tagging " ``` -------------------------------- ### Enforce HTTPS and Initialize Typekit Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_layouts/default.html Redirects traffic to HTTPS when on the production host and initializes Typekit within a try-catch block. ```javascript var host = "10up.github.io"; if ( window.location.host === host && window.location.protocol !== "https:" ) { window.location.protocol = "https:"; } {{ site.name }} try{Typekit.load();}catch(e){} ``` -------------------------------- ### Git Plugin Workflow: Gitflow with Semantic Versioning Source: https://context7.com/10up/engineering-best-practices/llms.txt Utilize the Gitflow workflow for plugins, incorporating semantic versioning and proper release tagging. Features branch off 'develop', releases are prepared on 'release' branches, and tagged on 'trunk'. ```sh # Feature development branches off develop git checkout develop git pull origin develop git checkout -b feature/add-settings-api # After feature complete, merge to develop git checkout develop git merge feature/add-settings-api --no-ff git push origin develop # Create release branch when ready git checkout develop git checkout -b release/1.2.0 # Bump version numbers in plugin header, readme.txt, etc. # Update CHANGELOG.md following Keep A Changelog format git add . git commit -m "Prepare release 1.2.0 - Bump version to 1.2.0 - Update changelog with new features and fixes" # Merge release to trunk and tag git checkout trunk git merge release/1.2.0 --no-ff git tag -a 1.2.0 -m "Release version 1.2.0" git push origin trunk --tags # Merge trunk back to develop git checkout develop git merge trunk --no-ff git push origin develop # Archive and delete release branch git tag archive/release-1.2.0 release/1.2.0 git branch -D release/1.2.0 git push origin :release/1.2.0 git push origin archive/release-1.2.0 ``` -------------------------------- ### Base Heading Styles with :where Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/CSS.md Establishes foundational styles for headings using the :where pseudo-class for zero specificity. Utilizes CSS custom properties for consistency and resets default margins. ```css :where(h1) { color: var(--color--heading); font-family: var(--font--family--heading); font-size: var(--font--size--heading-1); font-weight: var(--font--weight--heading); line-height: var(--font--line-height--heading-1); margin-block: 0; } ``` -------------------------------- ### Implement adaptive serving with Network Information API Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Performance.md Listen for network connection changes to adjust application behavior based on user connectivity. This can be used to toggle low-data modes or report network conditions to analytics. ```js navigator.connection.addEventListener("change", () => { sendBeacon(); // Send to Analytics if (navigator.connection.effectiveType === "2g" ) { body.classList.add("low-data-mode") } }); ``` -------------------------------- ### Enable InnoDB File Per Table Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Systems.md Enabling this setting ensures each InnoDB table has a dedicated file, allowing disk space to be reclaimed upon table deletion. Disable only if routinely creating and deleting hundreds of tables, which is uncommon for WordPress. ```sql innodb_file_per_table ``` -------------------------------- ### Configure EditorConfig settings Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Design.md Defines consistent coding styles across different IDEs and editors. Place this file in the project root directory. ```ini root = true [*] indent_style = space indent_size = 2 trim_trailing_whitespace = true [*.{php,js,css,scss}] end_of_line = lf insert_final_newline = true indent_style = tab indent_size = 4 ``` -------------------------------- ### Structure CSS Nesting Correctly Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/CSS.md Demonstrates acceptable nesting for state pseudo-classes while keeping element and modifier selectors flat. ```css /* block */ .button { /* ✅ state inside the block is fine */ &:hover { /* styles here */ } } /* ✅ element and modifier stay flat */ .button__icon { /* styles here */ } .button--primary { /* styles here */ } ``` -------------------------------- ### Preconnect to external origins Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Performance.md Establishes early network connections to critical third-party origins to reduce latency for above-the-fold resources. ```html ``` -------------------------------- ### Git Theme Workflow: Trunk-Based Development Source: https://context7.com/10up/engineering-best-practices/llms.txt Follow trunk-based development for themes. Create feature branches, keep them updated with trunk, and push for code review before merging to staging and then trunk. ```sh # Create feature branch from trunk git checkout trunk git pull origin trunk git checkout -b feature/add-hero-component # Make commits with descriptive messages git add . git commit -m "Add hero component with responsive image support - Implement srcset for responsive images - Add lazy loading for below-fold images - Include Schema.org markup for SEO" # Keep feature branch updated with trunk git checkout trunk git pull origin trunk git checkout feature/add-hero-component git merge trunk --no-ff # Push feature branch for code review git push -u origin feature/add-hero-component # After PR approval, merge to staging for testing git checkout staging git merge feature/add-hero-component --no-ff git push origin staging # After testing, merge to trunk for deployment git checkout trunk git merge feature/add-hero-component --no-ff git push origin trunk # Delete feature branch after merge git branch -D feature/add-hero-component git push origin :feature/add-hero-component ``` -------------------------------- ### Implement ITCSS Architecture with Low Specificity Source: https://context7.com/10up/engineering-best-practices/llms.txt Organize styles using the ITCSS structure, utilizing :where() to maintain zero specificity for base elements and CSS custom properties for global configuration. ```css /* ============================================ SETTINGS - Global variables and configurations ============================================ */ :root { /* Colors */ --color-primary: #0066cc; --color-secondary: #333333; --color-background: #ffffff; --color-text: #1a1a1a; /* Typography */ --font-family-base: system-ui, -apple-system, sans-serif; --font-family-heading: Georgia, serif; --font-size-base: 1rem; --line-height-base: 1.5; /* Spacing */ --spacing-xs: 0.25rem; --spacing-sm: 0.5rem; --spacing-md: 1rem; --spacing-lg: 2rem; } /* ============================================ GENERIC - Reset and global rules ============================================ */ *, *::before, *::after { box-sizing: border-box; } :where(body) { margin: 0; font-family: var(--font-family-base); line-height: var(--line-height-base); color: var(--color-text); } /* ============================================ ELEMENTS - Bare HTML elements (use :where for zero specificity) ============================================ */ :where(h1, h2, h3, h4, h5, h6) { font-family: var(--font-family-heading); margin-block: 0; line-height: 1.2; } :where(h1) { font-size: clamp(2rem, 5vw, 3rem); } :where(h2) { font-size: clamp(1.5rem, 4vw, 2.25rem); } :where(p) { margin-block: 0; } :where(a) { color: var(--color-primary); text-decoration-skip-ink: auto; } /* ============================================ COMPONENTS - UI components with single class specificity ============================================ */ .card { background-color: var(--color-background); border-radius: 0.5rem; overflow: hidden; /* NO margins - spacing handled by parent container */ } .card__image { aspect-ratio: 16 / 9; object-fit: cover; width: 100%; } .card__content { padding: var(--spacing-md); } .card__title { color: var(--color-secondary); } /* Component spacing handled by parent, not the component */ .card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--spacing-lg); } /* State nested inside component is fine */ .button { background-color: var(--color-primary); color: white; padding: var(--spacing-sm) var(--spacing-md); border: none; cursor: pointer; } .button:hover { opacity: 0.9; } .button:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; } /* ============================================ UTILITIES - Single-purpose helper classes ============================================ */ .visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; } .text-center { text-align: center; } ``` -------------------------------- ### Implement Object Caching with Cache Priming Source: https://context7.com/10up/engineering-best-practices/llms.txt Refresh cache proactively by hooking into relevant actions rather than waiting for user requests. This ensures the cache remains warm and reduces database overhead. ```php have_posts() ) { // Cache without expiration - primed by comment count hook wp_cache_set( $cache_key, $top_commented_posts->posts, $cache_group ); } } return $top_commented_posts; } ?> ``` -------------------------------- ### Configure Temporary Table Sizes Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/Systems.md Modestly size `tmp_table_size` and `max_heap_table_size` (e.g., 8MB or 16MB) for efficient temporary table creation in memory. Larger values are often recommended by MySQLTuner but may not improve performance for WordPress sites with LONGTEXT or BLOB fields in joins. ```sql tmp_table_size = 16M ``` ```sql max_heap_table_size = 16M ``` -------------------------------- ### Insert Dynamic Content via innerHTML Source: https://github.com/10up/engineering-best-practices/blob/gh-pages/_includes/markdown/JavaScript.md Demonstrates a common but potentially insecure pattern for injecting HTML strings into the DOM. ```javascript const someElement = document.getElementById('someElement'); const someUrl = 'https://someurl.com/'; const someContent = 'Some content'; someElement.innerHTML = ``; ```