Skip to content

Liber Tertius · Chapter 5 · Working on modules

Create a theme

The scaffold switches your own machine to the new theme and tells nobody else. Two things make it real for the project, a tagged version that holds your work and a line in grim.json, and they are the two steps people forget.

≈30 min 6 steps A project that installs and runs Node and yarn on your machine The right to create repositories in the organisation
Source

Before you start

The project is installed, so it has an .env, and the stack runs. The scaffold patches .env and refuses to when the file is missing. yarn is on your machine, because the Vite dev server runs there and not in a container.

$ grim up
$ yarn --version
$ git status --short

The theme gets a repository of its own, grimoiry/grim-theme-<slug>, created with the token grim stored. Your GitHub account has to be allowed to create repositories in that organisation, and git needs a user.name and user.email. Without either, the theme is still created on disk and only the publishing is skipped.

A project has two theme slots. frontend is what visitors see, and admin is the back office. This recipe makes a frontend theme. For the other slot add --type=admin in step one and read THEME_ADMIN, themes.admin and --admin wherever the text says frontend.

The ritual, in order

Six steps. The first two change your machine only. The fifth and sixth are what reach your colleagues and the production build.

  1. Scaffold the theme

    grim make:theme writes resources/themes/frontend/shop-front/, points .env at it, makes the directory a git repository, creates the GitHub repository, and pushes main and a first version tag.

    $ grim make:theme shop-front --activate
    
      Theme shop-front created
      Path              resources/themes/frontend/shop-front/
      Type              frontend
      Activated         yes (.env patched)
      Remote repo       https://github.com/grimoiry/grim-theme-shop-front
      Reused existing   no
      Published         yes

    Read the Published row. no — 2 step(s) skipped does not fail the command, and it means the repository or the tag is missing. See When it does not work before you go on.

    What landed: theme.json, app.blade.php, functions.php, the entry points ts/frontend.ts and css/frontend.css, a standard layout, an index page, an email layout and six error pages. An admin theme is smaller: the manifest, app.blade.php, functions.php, ts/app.ts and css/app.css.

  2. Switch the project to it

    --activate wrote two lines into .env. The first tells the app which theme to render, and the second makes Vite build the same one. Containers read .env when they are created, so take the stack down with grim down and bring it up again.

    $ grep THEME_FRONTEND .env
    THEME_FRONTEND=shop-front
    VITE_THEME_FRONTEND=${THEME_FRONTEND}
    $ grim down
    $ grim up

    The second line is a reference to the first, not a copy, so switching themes later is an edit of one value. To go back to the previous theme, put its slug into THEME_FRONTEND and restart the same way. Both themes stay installed side by side.

  3. Work on it with Vite running

    grim up started yarn dev on your machine and left it in the background. While public/hot exists, the app loads assets from the dev server, and a saved file shows in the browser without a reload.

    $ tail -f .grim/vite.log

    Open https://shop.test and edit layouts/standard.blade.php and css/frontend.css in the theme directory. When a style does not arrive, the log is where Vite says why. A Development ready table without a Vite HMR row means yarn was not found, and nothing else reports that.

  4. Validate the manifest

    theme.json is short: name, description, version, type, and requires-modules, which the scaffold set to the frontend module. grim manifest:validate checks it against the rules the tag workflow enforces.

    $ grim manifest:validate resources/themes/frontend/shop-front

    Run it after every edit of the manifest. type has to stay frontend or admin, and version has to be a full X.Y.Z.

  5. Publish a version that holds your work

    The tag from step one, v2.5.0, points at the empty scaffold. A project installs themes by tag, so your work needs a tag of its own. Raise version in theme.json to 2.5.1, then commit, tag and push from inside the theme.

    $ git -C resources/themes/frontend/shop-front add -A
    $ git -C resources/themes/frontend/shop-front commit -m "feat: first layout and styles"
    $ git -C resources/themes/frontend/shop-front tag v2.5.1
    $ git -C resources/themes/frontend/shop-front push origin main v2.5.1

    Stay on the project's train: 2.5.x for a project on train 2.5. The tag starts the Validate workflow in the theme's repository, which fails when the tag and theme.json disagree. The scaffold ships no .gitignore. Add one before the first line if the directory holds anything you do not want published.

  6. Add it to the project

    make:theme never writes to grim.json, and the project's repository ignores resources/themes/. Until this step a colleague who clones the project gets the old theme. grim require finds the newest tag on the train, sees that your checkout already sits on it, and puts the theme at the front of its slot.

    $ grim require shop-front --frontend
    $ git add grim.json grim.lock
    $ git commit -m "feat: add shop-front theme"

    The first theme of a slot is the active one for a fresh install. The theme that was there before stays installed behind it.

What you have now

"themes": {
    "frontend": ["shop-front:~2.5", "blank:~2.5"]
}

On disk, resources/themes/frontend/shop-front/ is a git repository of its own on tag v2.5.1, and grimoiry/grim-theme-shop-front holds main and two tags. .env on your machine names the theme. A colleague's .env still names the old one after git pull and grim install, and they change THEME_FRONTEND by hand.

The production image is built with the theme .env names, so grim build on your machine already bundles shop-front. Later changes go out the way step five did: raise the version, commit, tag, push, and then grim update in every project that uses the theme.

⚠ .env THEME_FRONTEND=shop-front is not declared in grim.json themes.frontend … during a build is step six waiting to be done. The build goes on with the .env value, and the image is correct.

When it does not work

The Published row says no

no — 2 step(s) skipped means the theme is complete on disk and nothing reached GitHub. The warning above the table says which step failed, usually a missing git identity or a token that may not create repositories. Fix that, then finish by hand. grim prints the first two lines itself, and the tag is on you. When the first commit is missing as well, make it before the gh line.

$ cd resources/themes/frontend/shop-front
$ gh repo create grimoiry/grim-theme-shop-front --private --source=. --push
$ git tag v2.5.0
$ git push origin v2.5.0

The printed hint names grimoiry even when you passed --org. Do not pass --org for a theme a project should install. grim resolves every theme under grimoiry.

“.env not found at …”

run `grim install` / `grim up` first to generate it is the rest of the message. The theme was scaffolded before the step failed, and a second run refuses because the directory exists. Generate the .env, then add the two lines of step two by hand.

“Theme directory already exists: resources/themes/frontend/shop-front/”

An earlier run got as far as the scaffold. Work with what is there, or delete the directory and run the command again.

require leaves the theme out

A Skipped row with the theme's name in the Packages added table means no tag on the project's train was found. Check that step five pushed the tag and that its version starts with the train, 2.5. shop-front is not available means the repository does not exist under grimoiry.

The page renders without styles

The dev server is not running or builds another theme. Check that both lines of step two are in .env, read .grim/vite.log, and run grim down and grim up again.

Questions

What is grim install --allow-unpublished-theme for?

It makes install take one theme from its directory on disk and record the version from its theme.json, without looking for a tag. The named theme is also left out of the package check, so it works when the repository does not exist yet. grim create-project --new-theme passes it for you when the publish failed. It is a stopgap for one machine: a colleague who clones the project cannot install until the theme is published.

Can a theme be sent with grim push?

Only a theme that is released from the monorepo. One you created here has a repository of its own, and you push to it with git.