Skip to content

Commit

Permalink
Add cohesive developer documentation in /docs (WordPress#67)
Browse files Browse the repository at this point in the history
This PR populates /docs with a step-by-step documentation connecting the priors documentation efforts shipped in:

* API Reference documentation WordPress#63
* Migrate the project to TypeScript WordPress#61
* Add developer documentation  WordPress#60
* Monorepo WordPress#57
  • Loading branch information
adamziel authored Nov 7, 2022
1 parent 95fb0fd commit a2563cd
Show file tree
Hide file tree
Showing 17 changed files with 1,261 additions and 237 deletions.
42 changes: 15 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,28 @@
# WordPress in the browser!
# WordPress.wasm

WordPress.wasm is a client-side WordPress that runs without a PHP server thanks to the magic of WebAssembly.
[Live demo](https://wasm.wordpress.net/wordpress.html) | [Documentation](https://github.com/WordPress/wordpress-wasm/tree/trunk/docs) | [API Reference](https://github.com/WordPress/wordpress-wasm/tree/trunk/docs/api)

[See the live demo!](https://wasm.wordpress.net/wordpress.html)
WordPress.wasm is a client-side WordPress that runs without a PHP server thanks to the magic of WebAssembly.

![](demo.gif)
![](https://raw.githubusercontent.com/wordpress/wordpress-wasm/trunk/demo.gif)

Table of contents:

- [Why is this useful?](#why-is-this-useful)
- [Getting started](#getting-started)
- [Architecture overview](#architecture-overview)

## Why is this useful?
## Why is WordPress.wasm useful?

I'm glad you asked – WordPress.wasm is a big deal!

WordPress.wasm can power:
It can power:

* Runeditable code examples in your documentation or course
* Plugin and theme demos in a private WordPress instance where the user is already logged in as admin
* Easily switching PHP and WordPress version when testing
* Replaying and fixing the failed CI tests right in the browser
- Runeditable code examples in your documentation or course
- Plugin and theme demos in a private WordPress instance where the user is already logged in as admin
- Easily switching PHP and WordPress version when testing
- Replaying and fixing the failed CI tests right in the browser

WordPress.wasm provides a strong foundation for the above use-cases but does not implement them just yet. This project is still in its early days and needs contributors. Become a contributor today and help us make these tools a reality!

See
See
[the WordPress.org blog post](https://make.wordpress.org/core/2022/09/23/client-side-webassembly-wordpress-with-no-server/) to learn about the vision, other use-cases, and the visuals.

### Getting started
## Getting started

You can run WordPress.wasm as follows:

Expand All @@ -39,18 +33,12 @@ npm install
npm run dev
```

A browser should open and take you to your very own client-side WordPress at http://127.0.0.1:8777/wordpress.html!
A browser should open and take you to your very own client-side WordPress at http://127.0.0.1:8777/wordpress.html!

As of today, the best way to play with WordPress.wasm is to directly modify the cloned files – [packages/wordpress-wasm/](./packages/wordpress-wasm) is a good place to start.

Why aren't there any npm packages? This is a new project and didn't get there yet – all the efforts were focused on getting it to work. If you'd like to see public npm packages sooner than later, you are more than welcome to contribute.

## Architecture overview

WordPress.wasm is made of the following building blocks:

* [php-wasm](./packages/php-wasm) – a configurable PHP->WebAssembly build pipeline, convenient JavaScript bindings, and a PHP server implemented in JavaScript.
* [php-wasm-browser](./packages/php-wasm-browser) – tools to run real PHP apps in the browser via `php-wasm`, like a Service Worker implementation or Worker Threads to run the PHP runtime concurrently.
* [wordpress-wasm](./packages/wordpress-wasm) – runs WordPress in the browser using the other two packages.
## Next steps

Consult the linked README.md files in each of these packages to learn more.
Consult the [documentation](https://github.com/WordPress/wordpress-wasm/tree/trunk/docs) to learn how WordPress.wasm works and how you can help you build amazing things!
8 changes: 0 additions & 8 deletions build-docs.sh

This file was deleted.

35 changes: 34 additions & 1 deletion docs/api/php-wasm-browser.postmessageexpectreply.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,38 @@ postMessageExpectReply<!-- -->(\
* Returns: The message ID for awaitReply().


Posts a message branded with a unique `requestId` to the given `target`<!-- -->. Then returns the `requestId` so it can be used to await a reply.
Posts a message branded with a unique `requestId` to the given `target`<!-- -->. Then returns the `requestId` so it can be used to await a reply. Effectively, it implements the request/response dynamics on of JavaScript's `postMessage`

## Example
In the main app:

```js
import { postMessageExpectReply, awaitReply } from 'php-wasm-browser';
const iframeWindow = iframe.contentWindow;
const requestId = postMessageExpectReply(iframeWindow, {
type: "get_php_version"
});
const response = await awaitReply(iframeWindow, requestId);
console.log(response);
// "8.0.24"
```
In the iframe:

```js
import { responseTo } from 'php-wasm-browser';
window.addEventListener('message', (event) => {
let response = '8.0.24';
if(event.data.type === 'get_php_version') {
response = '8.0.24';
} else {
throw new Error(`Unexpected message type: ${event.data.type}`);
}

// When `requestId` is present, the other thread expects a response:
if (event.data.requestId) {
const response = responseTo(event.data.requestId, response);
window.parent.postMessage(response, event.origin);
}
});
```

File renamed without changes
File renamed without changes
150 changes: 150 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# WordPress in the browser!

WordPress.wasm is a client-side WordPress that runs without a PHP server thanks to the magic of WebAssembly. [See the live demo!](https://wasm.wordpress.net/wordpress.html)

Related resources:

- [Using PHP in Javascript](./using-php-in-javascript.md)
- [Using WordPress in the browser](./using-php-in-the-browser.md)
- [Using PHP in the browser](./using-wordpress-in-the-browser.md)
- [API Reference](./api)

## Getting started

You can run WordPress.wasm as follows:

```js
git clone https://github.com/WordPress/wordpress-wasm
cd wordpress-wasm
npm install
npm run dev
```

A browser should open and take you to your very own client-side WordPress at http://127.0.0.1:8777/wordpress.html!

## Creating your own WordPress.wasm app

As of today, the best way of building a WordPress.wasm app is by directly modifying the `wordpress-wasm` package. Unfortunately, there are no importable npm packages yet. They will get published, eventually, but so far all the efforts were focused on getting this project to work.

If you'd like to see public npm packages sooner than later, you are more than welcome to contribute!

## Basic usage

All the code examples in this sections will work only inside `packages/wordpress-wasm/src`.

### Controlling WordPress.wasm

The WordPress instance is controlled via the `workerThread` object:

```js
import { bootWordPress } from './';
const workerThread = await bootWordPress();
```

The `bootWordPress` utility downloads the WebAssembly runtime, starts it in a separate thread for performance reasons, and returns a `SpawnedWorkerThread` instance. The main application can control the WordPress instance through the `SpawnedWorkerThread` API.

For example, you can run PHP code using the `eval` method:

```js
const result = await workerThread.eval(`<?php echo "Hello, world!";`);
console.log(result);
// { stdout: "Hello, world!", stderr: [''], exitCode: 0 }
```

You can also dispatch HTTP requests to WordPress as follows:

```js
const response = await workerThread.HTTPRequest({
path: workerThread.pathToInternalUrl('/wp-login.php'),
method: 'GET',
});
console.log(response.statusCode);
// 200
console.log(response.body);
// ... the rendered wp-login.php page ...
```

For more details, see the `SpawnedWorkerThread` reference manual page and the architecture overview.

### Logging the user in

`wordpress-wasm` provides helpers to automate common use-cases, like logging the user in:

```js
import { login } from './macros';

// Authenticate the user by sending a POST request to
// /wp-login.php (via workerThread.HTTPRequest()):
await login(workerThread, 'admin', 'password');
```

### Installing plugins

You can install plugins using the `installPlugin()` helper:

```js
// Login as an admin first
await login(workerThread, 'admin', 'password');

// Download the plugin file
const pluginResponse = await fetch('/my-plugin.zip');
const blob = await pluginResponse.blob();
const pluginFile = new File([blob], 'my-plugin.zip);
// Install the plugin by uploading the zip file to
// /wp-admin/plugin-install.php?tab=upload
await installPlugin(workerThread, pluginFile);
```
## Advanced usage
To go beyond the basic usage, you'll need to understand the project architecture.

WordPress.wasm is made of the following building blocks:

### PHP in JavaScript

The `php-wasm` package enables running PHP in JavaScript. It consists of:

- PHP to WebAssembly build pipeline
- JavaScript bindings to run the WebAssembly PHP
- PHP server implementation in JavaScript

See [using PHP in Javascript](./using-php-in-javascript.md) to learn:

- How does the WebAssembly PHP work?
- How to customize the PHP installation?
- How to control the PHP runtime in JavaScript?

* How to create and delete files in the PHP filesystem?
* How does the PHP Server work?

### PHP in the browser

The `php-wasm-browser` package provides tools to run `php-wasm` in the browser:

![The boot sequence](https://raw.githubusercontent.com/wordpress/wordpress-wasm/trunk/docs/boot-sequence.png)

It consists of:

- Tools to load PHP and any dependencies over the internet.
- A Worker Thread implementation to offload the PHP runtime to.
- A Service Worker implementation to route the browser traffic to PHP.
- A messaging layer to wire all the processes together.
- PHP initialization progress monitor.

See [using PHP in the browser](./using-php-in-the-browser.md) to learn more.

### WordPress in the browser

The `wordpress-wasm` package runs WordPress in the browser with the help of `php-wasm` and `php-wasm-browser`.

It consists of:

- A page with "fake browser" UI where WordPress is displayed.
- A bundler for packaging a WordPress installation as an Emscripten data dependency.
- WordPress-specific setup for the Worker Thread and the Service Worker.
- WordPress-specific automations for tasks like signing in or installing plugins.
- A PHP proxy to download plugins from the WordPress.org directory.

See [using WordPress in the browser](./using-wordpress-in-the-browser.md) to learn more.
Loading

0 comments on commit a2563cd

Please sign in to comment.