Skip to content

Commit

Permalink
Svelte and React templates, lazy pages fix, adminBar page prop and im…
Browse files Browse the repository at this point in the history
…proved Vue template files #minor
  • Loading branch information
craigrileyuk committed Dec 21, 2024
1 parent 2fe1c80 commit 18bfd28
Show file tree
Hide file tree
Showing 39 changed files with 698 additions and 96 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Fetch and checkout the latest commit
run: |
git fetch origin main
git checkout origin/main
- uses: pnpm/action-setup@v2
with:
version: 9
Expand Down
37 changes: 21 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,55 +94,55 @@ Once your theme has been created, it will not be changed again by the Inertia Wo

If you ran the theme bootstrapper command above, you should have something like the above.

### app.php
> ### app.php
See [InertiaJS.com > Server-Side Setup > Root Template](https://inertiajs.com/server-side-setup#root-template)

### controllers
> ### controllers
These files will be the bridge between Wordpress and Inertia for serving GET requests. Each file should contain a single class that extends the `EvoMark\InertiaWordpress\InertiaController` class and provides a `handle` method. The handle method must return a call to `$this->render()`.

The files in this directory are loaded in accordance with [Wordpress' template hierarchy rules](https://developer.wordpress.org/themes/basics/template-hierarchy/), albeit moved from the root of your theme to this `controllers` directory.

### ecosystem.config.cjs
> ### ecosystem.config.cjs
This is an optional file provided to make running your InertiaJS SSR process easier. It is read by the PM2 process manager and keeps your process running reliably.

For more information see the page on [PM2 Ecosystem Files](https://pm2.keymetrics.io/docs/usage/application-declaration/)

### functions.php
> ### functions.php
The standard entry point for your theme. The bootstrapper will populate this with a call to REST API.
The standard entry point for your theme. The bootstrapper will populate this with a small amount of code.

The REST API is a call to [WP Rest Registration](https://evomark.co.uk/open-source-software/wp-rest-registration/) which allows you to easily register REST endpoints that can validated input.
The code `new RestApi` is a call to [WP Rest Registration](https://evomark.co.uk/open-source-software/wp-rest-registration/) which allows you to easily register REST API endpoints that can validate input.

We'll be using these to process information submitted by our InertiaJS frontend. See `rest-api` below for more details.
We'll be using these endpoints to process information submitted by our InertiaJS frontend. See `rest-api` below for more details.

### index.php
> ### index.php
Intentionally left empty to prevent directory indexing

### package.json
> ### package.json
A file used by NodeJS package managers to install dependencies required by your theme. Common package managers are `NPM`, `PNPM`, and `Yarn`.

### resources
> ### resources
This is where the majority of your themes frontend will live. It's no different from a standard InertiaJS project setup, so we won't go into much detail on the file structure.

### rest-api
> ### rest-api
Since InertiaJS sends its data via AJAX requests, we can't use our `controllers` classes to process it. Instead, we must use special REST API controllers.

All classes in this directory are automatically registered by the call the `new RestApi` in your `functions.php` file. The structure of these files should be familiar to anyone experienced with Laravel Controllers.

See the [WP REST Registration documentation](https://evomark.co.uk/open-source-software/wp-rest-registration/) for more details.

### style.css
> ### style.css
Required by Wordpress.

### vite.config.js
> ### vite.config.js
Used by Vite to bundle/build your theme's JavaScript and CSS files. You shouldn't need to change anything here to get Vite working, but feel free to add more plugins.

Expand Down Expand Up @@ -202,7 +202,7 @@ createInertiaApp({

The `resolveInertiaPage` accepts two arguments, the first is your pages glob. With `eager: true` the pages will all be bundled into a single file, whereas with `eager: false` Vite will use code-splitting when bundling your app.

The second argument the `resolveInertiaPage` accepts is your [Default Layout](https://inertiajs.com/pages#default-layouts). This can either be a standard layout/layout-array:
The second argument the `resolveInertiaPage` accepts is your [Default Layout](https://inertiajs.com/pages#default-layouts).

```js
import Layout from './Layout'
Expand All @@ -213,7 +213,7 @@ resolve: resolveInertiaPage(
),
```

or you can pass a function that should return a layout or layout-array:
A third argument can be an optional callback that receives the page name and page object and should return a valid Layout.

```js
import Layout1 from './Layout';
Expand All @@ -222,6 +222,7 @@ import Layout2 from './Layout2';
// ...
resolve: resolveInertiaPage(
import.meta.glob("./pages/**/*.vue", { eager: false }),
null, // Notice that the 2nd argument is null
/**
* @param { string } name The page name that is being loaded
* @param { VNode } resolvedPage The resolved page vNode
Expand All @@ -237,10 +238,14 @@ resolve: resolveInertiaPage(

If you check your Inertia page props, you'll see a few provided objects pre-loaded:

- **$page.props.wp.adminBar**: _Coming Soon_
- **$page.props.wp.name**: The name of your site
- **$page.props.wp.homeUrl**: The URL of your site's homepage
- **$page.props.wp.restUrl**: The base URL for making REST API requests
- **$page.props.wp.user**: The user object for the currently logged in user
- **$page.props.wp.userCapabilities**: An object of the current users capabilities/permission
- **$page.props.wp.logo**: An image resource containing your site logo as set in Wordpress' Appearance->Customise menu
- **$page.props.wp.menus**: A nested object containing your registered menus, keyed by location
- **$page.props.wp.adminBar**: _Coming Soon_

## Wordpress Settings

Expand Down
7 changes: 7 additions & 0 deletions changelog/next.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
- **Feature**: Svelte template now available via `wp inertia:create-theme` command
- **Feature**: React template now available via `wp inertia:create-theme` command
- **Feature**: Edit and Comment nodes returned via `wp.adminBar` on Inertia requests

- **Improvement**: Included more detailed templates/layouts for theme bootstrapper

- **BugFix**: Duplicated inertia instances when using code-splitting on pages
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"require": {
"php": ">=8.2",
"evo-mark/evo-wp-rest-registration": "^4.1",
"evo-mark/wp-vite": "^1.1",
"evo-mark/wp-vite": "^1.2",
"guzzlehttp/guzzle": "^7.9",
"illuminate/collections": "^11.35",
"nesbot/carbon": "^3.8",
Expand Down Expand Up @@ -58,4 +58,4 @@
},
"minimum-stability": "dev",
"prefer-stable": true
}
}
44 changes: 22 additions & 22 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 21 additions & 17 deletions resources/plugins/index.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
export const resolveInertiaPage = (glob, layout = null) => {
return async function (name) {
let resolvedPage = glob[`./pages/${name}.vue`];
if (!resolvedPage) {
console.error(`[Inertia] Couldn't find page matching "${name}"`);
return null;
}
export const resolveInertiaPage = (
glob,
layout = null,
layoutCallback = null
) => {
return async function (name) {
let resolvedPage = glob[`./pages/${name}.vue`];
if (!resolvedPage) {
console.error(`[Inertia] Couldn't find page matching "${name}"`);
return null;
}

if (typeof resolvedPage === "function") {
resolvedPage = await resolvedPage();
}
if (typeof resolvedPage === "function") {
resolvedPage = await resolvedPage();
}

if (typeof layout === "function") {
resolvedPage.default.layout = layout(name, resolvedPage);
} else if (layout) {
resolvedPage.default.layout = layout;
}
if (layoutCallback) {
resolvedPage.default.layout = layoutCallback(name, resolvedPage);
} else if (layout) {
resolvedPage.default.layout = resolvedPage.default.layout || layout;
}

return resolvedPage;
};
return resolvedPage;
};
};
8 changes: 8 additions & 0 deletions resources/plugins/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@
".": {
"import": "./index.js",
"require": "./index.js"
},
"./react": {
"import": "./react.jsx",
"require": "./react.jsx"
},
"./svelte": {
"import": "./svelte.js",
"require": "./svelte.js"
}
},
"scripts": {
Expand Down
26 changes: 26 additions & 0 deletions resources/plugins/react.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export const resolveInertiaPage = (
glob,
Layout = null,
layoutCallback = null
) => {
return async function (name) {
let resolvedPage = glob[`./pages/${name}.jsx`];
if (!resolvedPage) {
console.error(`[Inertia] Couldn't find page matching "${name}"`);
return null;
}

if (typeof resolvedPage === "function") {
resolvedPage = await resolvedPage();
}

if (layoutCallback) {
resolvedPage.default.layout = layoutCallback(name, resolvedPage);
} else if (Layout) {
resolvedPage.default.layout =
resolvedPage.default.layout || ((page) => <Layout children={page} />);
}

return resolvedPage;
};
};
29 changes: 29 additions & 0 deletions resources/plugins/svelte.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export const resolveInertiaPage = (
glob,
layout = null,
layoutCallback = null
) => {
return async function (name) {
let resolvedPage = glob[`./pages/${name}.svelte`];
if (!resolvedPage) {
console.error(`[Inertia] Couldn't find page matching "${name}"`);
return null;
}

if (typeof resolvedPage === "function") {
resolvedPage = await resolvedPage();
}

if (layoutCallback) {
return {
default: resolvedPage.default,
layout: layoutCallback(name, resolvedPage),
};
} else {
return {
default: resolvedPage.default,
layout: resolvedPage.layout || layout,
};
}
};
};
Loading

0 comments on commit 18bfd28

Please sign in to comment.