Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions src/wp-content/themes/ipsum/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# AGENTS.md

How coding agents should work on Ipsum, in its GitHub repository or in any other copy of the theme, such as the one bundled with WordPress. This file covers what is specific to the theme and easy to get wrong. [DESIGN.md](DESIGN.md) says how to design with it.

## Working in the GitHub repository

In the [GitHub repository](https://github.com/WordPress/ipsum), read [CONTRIBUTING.md](https://github.com/WordPress/ipsum/blob/trunk/CONTRIBUTING.md) before you set up the development environment, run the checks or open a pull request. Other copies of the theme, such as the one in WordPress core, don't have that tooling.

## Key directories

Templates, patterns, `theme.json` and CSS are served as they are in the tree. The only generated file is `style.min.css`.

- `templates/*.html` - Block templates. Each is a one-line delegate to a pattern.
- `parts/*.html` - Template parts. Each is a one-line delegate to a pattern.
- `patterns/*.php` - The markup of every template and part, plus the insertable patterns.
- `styles/colors/*.json` - Color style variations, number-prefixed to control their order.
- `styles/typography/*.json` - Typography style variations.
- `styles/blocks/*.json` - Block style variations. The `slug` is used in markup as `is-style-<slug>`.
- `assets/fonts/` - Self-hosted fonts, one directory per family, credited under `== Fonts ==` in `readme.txt`.
- `assets/css/editor-style.css` - Editor-only overrides, loaded after `style.css` in the editors.
- `functions.php` - Theme PHP: stylesheets, the comments CTA block binding, sidebar template types, block styles. It loads `inc/abilities.php`.
- `inc/abilities.php` - The `ipsum/get-design-guide` ability, which gives agents on a live site the palette roles, presets, style variations, block styles, patterns and templates through the Abilities API. A new palette color needs its role in `ipsum_get_color_roles()`.
- `theme.json` - Global settings and styles, fonts, `customTemplates`, per-block styles.
- `style.css` - The theme header plus the CSS that `theme.json` cannot express. It loads in the editors through `add_editor_style()`, and is inlined on the front end when `SCRIPT_DEBUG` is on.
- `style.min.css` - `style.css` minified by `npm run build`, inlined on the front end otherwise. Generated: rebuild it, never edit it.
- `readme.txt` - The WordPress.org readme: description, changelog, copyright, font credits.

## Progressive discovery

Read only what your task needs, when it needs it:

- **Styling, or building pages, patterns or templates**: read [DESIGN.md](DESIGN.md) first. It covers the color roles, the type and spacing scales, the style variations, and which pattern fills each template and part.
- **Adding or changing a pattern**: read [Writing patterns](DESIGN.md#writing-patterns) in DESIGN.md first. It covers categories, hiding from the inserter, which i18n function to use, images, and removing `id`, `queryId`, `theme`, `area`, `patternName` and `metadata.categories` from copied markup.
- **Adding CSS or PHP**: read [Development guidelines](https://github.com/WordPress/ipsum/blob/trunk/CONTRIBUTING.md#development-guidelines). Prefer `theme.json` and Global Styles; add CSS or PHP only when the editor cannot express the design, and keep it commented.

## Markdown files

Ipsum's Markdown files are soft-wrapped: a paragraph, list item or table row is one line, however long. Do not hard-wrap prose, and do not re-flow lines a change does not otherwise touch.

## Architectural decisions

- **The pattern is the source of truth.** `templates/index.html` is `<!-- wp:pattern {"slug":"ipsum/hidden-index"} /-->` and nothing else. Editing a delegate template or part changes nothing at render time; edit the pattern it names. A pattern that only fills a template or part is hidden from the inserter with `Inserter: no`, and its file and slug take the `hidden-` prefix (`patterns/hidden-index.php` is `ipsum/hidden-index`); template patterns also carry `Template Types:`. Insertable patterns use `Categories`, `Block Types`, `Viewport width` and `Description`.
- **Style with the design tokens, not literals.** Colors come from `var(--wp--preset--color--<slug>)`, spacing from `var:preset|spacing|N`. The palette uses the Twenty Twenty-Five slugs, so default theme patterns pick up Ipsum's colors: `base` (Base) is the background, `contrast` (Contrast) the text, headings, links and buttons, `accent-1` (Accent) the accent, which only the arrival bar uses, `accent-3` (Strong Contrast) the hover color and the ground of inverted sections and cards, `accent-5` (Surface) the faint wash behind quotes, tags and cards, and `accent-6` (Border) the faint lines. `accent-2` and `accent-4` are not defined. Every color variation redefines all six, so a literal hex freezes one variation's look into all the others. `settings.custom.controlScheme` says whether the active palette is `light` or `dark`.
- **CSS explains why, in prose.** Rules in `style.css` and `assets/css/editor-style.css` carry a comment saying why they exist, often with the Gutenberg or Trac issue behind it. `css` strings in `theme.json` cannot hold comments.
- **Text domain is `ipsum`.** Every user-visible string goes through an i18n function, including single characters such as the `·` separators.
- **PHP follows the WordPress coding standards**, in tabs. Functions in `functions.php` and `inc/` are wrapped in `if ( ! function_exists( '…' ) ) : … endif;`, every docblock carries `@since Ipsum 1.0`, and `@package Ipsum` heads the file.

## Do not reformat block markup

The delimiters in templates, parts and patterns are Gutenberg's serialization, not hand-written HTML: flush left, one delimiter per line, a blank line between sibling blocks, and a block's wrapper element on the same line as the opening delimiter of its first child:

```html
<!-- wp:group {"metadata":{"name":"Body"},"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:post-title /-->
```

Reindenting or rewrapping it produces a large diff that the next editor round-trip undoes.
64 changes: 63 additions & 1 deletion src/wp-content/themes/ipsum/DESIGN.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# DESIGN.md

How to design with Ipsum: what each preset is for, how the theme uses it, and what the style variations, templates, parts and block styles give you. `AGENTS.md` covers working in the repository.
How to design with Ipsum: what each preset is for, how the theme uses it, and what the style variations, templates, parts and block styles give you. [Writing patterns](#writing-patterns) covers what a new pattern needs. [AGENTS.md](AGENTS.md) covers working on the theme's files.

## Ipsum

Expand Down Expand Up @@ -251,3 +251,65 @@ The separator between meta items is built three ways, on purpose:
- **Where both neighbours always render** (post date · categories), it's a Paragraph named Meta Separator: small, weight 600, with the dot hidden from screen readers. The row's block gap (`spacing|20`) spaces it. To add one, copy it from an archive pattern.
- **Where the whole row can go** (comments link · call to action), it's the same Paragraph, and the `comments-meta` class hides the row when comments are closed.
- **Where a neighbour may not render**, it's the Dot Separator style. The Edit link only renders for people who can edit the comment, and the Reply link only when threading allows it, so a Paragraph would be left behind as a stray dot. Use the Paragraph wherever it's safe: unlike the style's dot, it can be translated.

## Writing patterns

What a pattern in Ipsum needs, on top of the [block patterns reference](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-patterns/).

### Files and headers

- **File names:** full page layouts take the `page-` prefix, and patterns that only fill a template or part take `hidden-`. The inserter sorts patterns by file name, so the name also sets their order.
- **Categories:** use the [default categories](https://github.com/WordPress/gutenberg/blob/c20350c1d246163201375f090b0b7b4ab49b1dad/packages/block-editor/src/components/inserter/block-patterns-tab.js#L35), separated by commas, plus the two that `functions.php` registers: `ipsum_page` (Pages) for full page layouts and `ipsum_post-format` (Post formats) for post format patterns.
- **Hiding from the inserter:** a pattern people shouldn't insert on its own, such as one that only fills a template or part, or one that exists to make a template's text translatable, like the 404 pattern, carries ` * Inserter: no`.
- **Title and Description:** every pattern needs both, hidden ones too, since agents read them through the REST API (`/wp/v2/block-patterns/patterns`). Write full sentences, not dashes: what the pattern is, then a second sentence on what's in it. A hidden pattern says which template or template part it fills.
- **Block Types:** suggests the pattern when someone inserts that block or template part, such as a Query, Post Content, header or footer. Header, footer and navigation overlay patterns take `Block Types: core/template-part/<area>`. Patterns for General parts, like the sidebar and the search bar, leave it out, or the Site Editor offers each one as a design for every other General part.
- **Template Types:** suggests the pattern for a template, by slug (`404`, `home`, `single` and so on). Every template pattern takes it.
- **Post Types:** limits the pattern to those post types, usually for full page patterns.

### Strings

Every user-visible string goes through an [i18n function](https://developer.wordpress.org/apis/internationalization/internationalization-guidelines/) with the `ipsum` text domain, so it's translatable and escaped:

- `esc_html__()` translates and escapes text shown in HTML, and `esc_html_x()` does the same with a context for translators. `esc_html_e()` echoes it as well.
- `esc_attr__()` and `esc_attr_x()` translate and escape text that goes in an HTML attribute, such as alt text.
- For simple HTML inside a string, use `echo wp_kses_post( __( 'Lorem ipsum <em>Hello</em> dolor sit amet.', 'ipsum' ) );`. It's clearer for translators than `sprintf()`, and they can drop the markup where it doesn't work in their language.

### Images

- Build image URLs with `get_parent_theme_file_uri()` and the image's path in the theme. The URL then works wherever the site lives and from a child theme, and it can be filtered with `parent_theme_file_uri`, for example to serve the images from a CDN.
- Don't add a `?ver=` query argument. The images won't change after release, and once a pattern is inserted, its image URL is saved in the post, so the version would never update there anyway.
- Give every image translated alt text, and remove its ID, both the `id` attribute and the `wp-image-<id>` class.
- Credit every image's license under `== Images ==` in `readme.txt`.

An image copied from the editor:

```html
<!-- wp:image {"id":125,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="http://wp-stable.test/wp-content/themes/ipsum/assets/images/project.webp" alt="" class="wp-image-125"/></figure>
<!-- /wp:image -->
```

becomes:

```html
<!-- wp:image {"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="<?php echo esc_url( get_parent_theme_file_uri( 'assets/images/project.webp' ) ); ?>" alt="<?php echo esc_attr_x( 'Picture of a building', 'Alt text for project picture', 'ipsum' ); ?>"/></figure>
<!-- /wp:image -->
```

### Presets

- Use the spacing, font size and color presets, never fixed values. They keep the design consistent, let a style variation or Global Styles change it in one place, and keep patterns readable for more people. The sections above say what each preset is for.
- If you keep setting the same property on the same block, such as a border radius on images, move it to `theme.json`.

### Cleaning up copied markup

Markup built in the editor, or exported with a tool like Create Block Theme, carries attributes that don't belong in a pattern. Remove them; the editor adds back what it needs when the pattern is inserted.

- **`queryId` on Query blocks**, like the image IDs above: `<!-- wp:query {"queryId":18,"query":{"perPage":8,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":true}} -->` becomes `<!-- wp:query {"query":{"perPage":8,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":true}} -->`.
- **`theme` and `area` on template part blocks.** The area comes from `templateParts` in `theme.json`, so the slug is enough: `<!-- wp:template-part {"slug":"header-portfolio","theme":"ipsum","area":"header","tagName":"header"} /-->` becomes `<!-- wp:template-part {"slug":"header-portfolio","tagName":"header"} /-->`.
- **`patternName` and `categories` in block metadata.** The editor writes them into blocks inserted from a pattern. Keep the rest of the metadata, such as `name` or `bindings`: `<!-- wp:group {"metadata":{"name":"Footer","patternName":"ipsum/footer","categories":["footer"]},"layout":{"type":"constrained"}} -->` becomes `<!-- wp:group {"metadata":{"name":"Footer"},"layout":{"type":"constrained"}} -->`.

### Block names

Block names (`metadata.name`) show in the List View, and they're what an agent reads to tell blocks apart. Name a block by what it does, not what it prints: the paragraph holding the `·` separator is `Meta Separator`, not `·`. Translate names like other strings: `esc_html_x( 'Meta Separator', 'Name of the paragraph separating post meta items', 'ipsum' )`.
4 changes: 2 additions & 2 deletions src/wp-content/themes/ipsum/contributing.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
=== Contributing to Ipsum ===

Ipsum is developed at https://github.com/WordPress/ipsum. Changes made there are synced to WordPress core, so please open issues and pull requests in that repository.
Ipsum is developed on GitHub, at https://github.com/WordPress/ipsum, until its 1.0 release. Changes made there are synced to WordPress core, so until then, please open issues and pull requests in that repository. After 1.0, the GitHub repository is archived, and contributions go through Trac, https://core.trac.wordpress.org, like for the other bundled themes.

= Minifying CSS =

Ipsum has a single stylesheet `style.css` which is enqueued in addition to the global styles coming from core. On a normal production site, when `SCRIPT_DEBUG` is disabled, then the minified version `style.min.css` will be enqueued instead, unless `style.css` has changed since `style.min.css` was built. If you make a change to `style.css`, you'll need to re-minify the `style.min.css` using the built-in npm build tool. As always, it is preferable to use the Site Editor to supply Additional CSS instead of directly editing the theme stylesheet.
Ipsum has a single stylesheet `style.css` which is enqueued in addition to the global styles coming from core. On a normal production site, when `SCRIPT_DEBUG` is disabled, then the minified version `style.min.css` will be enqueued instead. If you make a change to `style.css`, you'll need to re-minify the `style.min.css` using the built-in npm build tool. As always, it is preferable to use the Site Editor to supply Additional CSS instead of directly editing the theme stylesheet.

Installation instructions

Expand Down
20 changes: 3 additions & 17 deletions src/wp-content/themes/ipsum/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,9 @@ function ipsum_add_theme_support() {
* @return void
*/
function ipsum_enqueue_styles() {
$style_path = get_parent_theme_file_path( 'style.css' );
$style_min_path = get_parent_theme_file_path( 'style.min.css' );

/*
* Use the minified stylesheet, unless script debugging is on or style.css
* has changed since style.min.css was built. That keeps edits made in the
* Theme File Editor working: saving style.css makes it the newer file.
*/
if (
SCRIPT_DEBUG
|| ! file_exists( $style_min_path )
|| ( filemtime( $style_path ) > filemtime( $style_min_path ) )
) {
$src = 'style.css';
} else {
$src = 'style.min.css';
}
// Use the minified stylesheet unless script debugging is on, as Twenty Twenty-Five does.
$suffix = SCRIPT_DEBUG ? '' : '.min';
$src = 'style' . $suffix . '.css';

// Register theme stylesheet.
wp_register_style(
Expand Down
Loading
Loading