# Configuration Reference This document defines every JSON field for both the global config and per-directory manifests. ## Global Config (`~/.config/wp-materialize/config.json`) Top-level fields: 1. `wordpress_root` (string, required) Path to the WordPress root directory where the `wp` CLI is executed. 2. `repo_storage_dir` (string, required) Directory where git repositories are cloned or updated. 3. `renderer` (string, optional) Markdown renderer to use. Allowed values: `default`, `py-gfm`, `pandoc`. 4. `hard_line_breaks` (boolean, optional) If `true`, treat single newlines as hard line breaks. 5. `block_html` (boolean, optional) If `true`, wrap HTML in a single Gutenberg HTML block to preserve formatting in the visual editor. 6. `git_repositories` (array, optional) List of git repositories to manage. Default is an empty list. 7. `directories` (array, optional) List of non-git directories to manage. Default is an empty list. `git_repositories` entries: 1. `name` (string, required) Stable identifier for the repository. Used to build post identity. 2. `url` (string, required) Git clone URL. 3. `branch` (string, optional, default `main`) Branch to checkout and pull. 4. `root_subdir` (string, optional) Subdirectory within the repo that contains `.wp-materialize.json` and content. If omitted or `null`, the repo root is used. `directories` entries: 1. `name` (string, required) Stable identifier for the directory. Used to build post identity. 2. `path` (string, required) Filesystem path to the directory. 3. `root_subdir` (string, optional) Subdirectory within the directory that contains `.wp-materialize.json` and content. If omitted or `null`, the directory root is used. ## Per-Directory Manifest (`.wp-materialize.json`) Each managed directory must contain a manifest. Manifests define a scope boundary. No implicit traversal is allowed; subdirectories must be listed explicitly. Top-level fields: 1. `categories` (object, optional) Inherited category paths for this directory and its children. 2. `tags` (object, optional) Inherited tags for this directory and its children. 3. `author` (object, optional) Inherited author for this directory and its children. Must resolve to a single author. 4. `renderer` (string, optional) Markdown renderer to use for this directory. Allowed values: `default`, `py-gfm`, `pandoc`. If omitted, it inherits from the parent scope. 5. `hard_line_breaks` (boolean, optional) If `true`, treat single newlines as hard line breaks. If omitted, it inherits from the parent scope. 6. `block_html` (boolean, optional) If `true`, wrap HTML in a single Gutenberg HTML block to preserve formatting. If omitted, it inherits from the parent scope. 7. `subdirectories` (object, optional) Explicit list of subdirectories to traverse. 8. `files` (object, optional) Mapping of Markdown file names to file-level configuration. `categories`, `tags`, `author`, and `subdirectories` objects: 1. `content` (array of strings, optional) List of values for the given field. For `categories`, each string is a hierarchical path such as `Systems/Infrastructure`. For `subdirectories`, each string is a directory name under the current directory. For `author`, exactly one string must remain after inheritance is applied and it should be a WordPress user ID (integer as a string). 2. `inherit` (boolean, optional, default `true`) If `true`, append to the parent effective list. If `false`, replace the parent list entirely. Note: Root directory manifests do not need to specify `inherit` for these top-level fields (the default is `true`). File-level overrides inside `files` still support inheritance via their own `inherit` fields. The `renderer` field inherits implicitly: if omitted, the renderer is inherited from the parent scope; if specified, it overrides the parent without an explicit `inherit` flag. The `hard_line_breaks` field inherits implicitly: if omitted, the value is inherited from the parent scope; if specified, it overrides the parent without an explicit `inherit` flag. The `block_html` field inherits implicitly: if omitted, the value is inherited from the parent scope; if specified, it overrides the parent without an explicit `inherit` flag. Renderer dependencies: 1. `default` uses the Python `Markdown` library. 2. `py-gfm` requires the `py_gfm` package (imported as `mdx_gfm`). 3. `pandoc` requires the `pandoc` binary to be available on PATH. `files` entries: Each key is a Markdown file name (relative to the manifest directory). Each value is an object with the following fields: 1. `title` (string, required if `use_heading_as_title` is not set) Explicit WordPress post title. 2. `use_heading_as_title` (object, optional) Extracts a heading from the Markdown as the title and removes that heading from the body while promoting remaining headings by one level. 3. `created_on` (string, optional) Manual override for the post creation time in `YYYY-MM-DD hh:mm` format. 4. `last_modified` (string, optional) Manual override for the post modified time in `YYYY-MM-DD hh:mm` format. 5. `renderer` (string, optional) Markdown renderer to use for this file. Allowed values: `default`, `py-gfm`, `pandoc`. If omitted, it inherits from the parent scope. 6. `hard_line_breaks` (boolean, optional) If `true`, treat single newlines as hard line breaks. If omitted, it inherits from the parent scope. 7. `block_html` (boolean, optional) If `true`, wrap HTML in a single Gutenberg HTML block to preserve formatting. If omitted, it inherits from the parent scope. 8. `categories` (object, optional) Overrides categories for this file. Uses the same `content` and `inherit` fields as the top-level `categories` object. 9. `tags` (object, optional) Overrides tags for this file. Uses the same `content` and `inherit` fields as the top-level `tags` object. `use_heading_as_title` object: 1. `level` (integer, required) Heading level to extract, from `1` to `6`. 2. `strict` (boolean, optional, default `true`) If `true`, exactly one matching heading must exist. If `created_on` or `last_modified` is not provided, the system infers the value. For `git_repositories` sources it uses git commit timestamps; for `directories` sources it uses filesystem timestamps. The system does not auto-detect git for entries declared under `directories`, even if the path is inside a git repo. If `created_on` is in the future, WordPress will mark the post as scheduled. ## Post Identity Each post is identified with: ``` _wp_materialize_source = : ``` `source_name` is the `name` from the global config entry, and `relative_path` is relative to the repo or directory root used for identity resolution. ## Tag and Category Creation Missing categories and tags are created automatically during apply, after a successful dry-run evaluation and before any post updates.