Skip to content
Closed
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
82 changes: 80 additions & 2 deletions packages/shared-utils/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,91 @@
# @yardinternet/shared-utils

Shared utilities used internally by `@yardinternet/toolkit` and `@yardinternet/vite-config`.
Shared utilities used internally by the other toolkit packages. It resolves the
project layout — where the themes live, which theme is the parent, and what URL
the built assets are served from — so every package agrees on one answer.

Ships both formats without a build step: ESM consumers `import`, CommonJS
consumers (eslint, prettier and postcss configs) `require`.

## Usage

```js
import { resolveThemeContext, getAllThemeNames } from '@yardinternet/shared-utils';

const { resolveThemeContext } = require( '@yardinternet/shared-utils' );
```

## Project layout detection

Two layouts are supported:

- **brave-root** — cwd is the project root and themes live in a themes
directory. Tooling operates on every theme.
- **theme-root** — cwd is a single theme (it has a `style.css` and no themes
directory). Every path collapses to the cwd, so a theme builds, watches, lints
and formats on its own.

### Themes directory

Resolved in this order, first hit wins. A candidate only counts when it actually
contains a theme, and `web/app/themes` is probed first, so existing Bedrock
projects resolve exactly as they always did.

1. `themesDir` in `yard-toolkit.config.json`, or in the `yardToolkit` key of
`package.json`.
2. The `YARD_THEMES_DIR` environment variable.
3. `composer.json` → `extra.installer-paths` entry for `type:wordpress-theme`.
4. A probe of the known layouts: `web/app/themes`, `wp-content/themes`,
`app/themes`, `public/wp-content/themes`, `content/themes`.
5. A `style.css` in the cwd → theme-root.

Nothing matched throws, listing what was tried.

### Asset base URL

The URL prefix built assets are served from is derived from where the themes
directory sits relative to the WordPress docroot (the nearest ancestor holding
an `index.php` or `wp-config.php`):

| Layout | Themes directory | Asset base URL |
| -------------------------- | -------------------- | -------------------- |
| Bedrock | `web/app/themes` | `/app/themes` |
| Classic WordPress | `wp-content/themes` | `/wp-content/themes` |

Override with `themesBaseUrl` in the config when a project serves its docroot
from somewhere unusual.

### Parent and child themes

Read from each theme's `style.css` header: a `Template:` field means the theme
is a child of that template, its absence means the theme is a parent. No
configuration involved — this is what WordPress itself uses.

The default theme (the one hosting the dev server, and the target of the
`@sage` compatibility aliases) is picked in this order: the configured
`defaultTheme`, the only parent, a parent named `sage`, then the first parent
alphabetically with a warning.

### Configuration

Only needed when auto-detection cannot get there:

```jsonc
// yard-toolkit.config.json, or the "yardToolkit" key in package.json
{
"themesDir": "site/wp-content/themes",
"themesBaseUrl": "/wp-content/themes",
"defaultTheme": "basis"
}
```

Run `yard-toolkit info` to see what was resolved and which layer won.

## Contents

- **Theme context** (`resolveThemeContext`, `getAllThemeNames`) — theme discovery for brave-root / theme-root project layouts.
- `resolveThemeContext( { cwd } )` — the full resolved layout. Memoized per
directory; throws when nothing resolves.
- `tryResolveThemeContext( { cwd } )` — same, returning `null` instead of
throwing. Use it in configs loaded by long-lived editor processes.
- `getAllThemeNames()`, `getParentThemes()`, `getThemesBaseUrl()`.
- `clearThemeContextCache()` — for tests.
9 changes: 8 additions & 1 deletion packages/shared-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@
"description": "Shared utilities used by @yardinternet/toolkit and @yardinternet/vite-config",
"main": "src/index.js",
"type": "module",
"exports": {
".": {
"require": "./src/resolve-theme-context.cjs",
"import": "./src/index.js"
},
"./package.json": "./package.json"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "vitest run"
},
"publishConfig": {
"registry": "https://npm.pkg.github.com/"
Expand Down
18 changes: 16 additions & 2 deletions packages/shared-utils/src/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
export { resolveThemeContext } from './resolve-theme-context.js';
export { getAllThemeNames } from './get-all-theme-names.js';
/**
* ESM facade over the CommonJS resolver, so the CJS configs (eslint, prettier,
* postcss) and the ESM packages (toolkit, vite-config) share one
* implementation without a build step.
*
* Properties are read off the default export rather than re-exported by name,
* so resolution never depends on CJS named-export detection.
*/
import themeContext from './resolve-theme-context.cjs';

export const resolveThemeContext = themeContext.resolveThemeContext;
export const tryResolveThemeContext = themeContext.tryResolveThemeContext;
export const getAllThemeNames = themeContext.getAllThemeNames;
export const getParentThemes = themeContext.getParentThemes;
export const getThemesBaseUrl = themeContext.getThemesBaseUrl;
export const clearThemeContextCache = themeContext.clearThemeContextCache;
Loading
Loading