Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doc: Explore migrating to MDX #323

Closed
adamziel opened this issue May 12, 2023 · 4 comments
Closed

Doc: Explore migrating to MDX #323

adamziel opened this issue May 12, 2023 · 4 comments
Labels
[Type] Documentation Improvements or additions to documentation [Type] Enhancement New feature or request

Comments

@adamziel
Copy link
Collaborator

adamziel commented May 12, 2023

Reusing doc is a challenge, e.g. I'd like to embed plenty of Blueprint steps docs on the "Getting started" page. MDX seems to be tailored for that and it integrates with Docusaurus.

https://mdxjs.com/

My ideal use-case is to have the following TypeScript::

/**
 * The step to install a WordPress plugin in the Playground.
 *
 * @example
 *
 * <code>
 * {
 * 	    "step": "installPlugin",
 * 		"pluginZipFile": "http://example.com/plugin.zip",
 * 		"options": {
 * 			"activate": true
 * 		}
 * }
 * </code>
 */
export interface InstallPluginStep<ResourceType> {
	/**
	 * The step identifier.
	 */
	step: 'installPlugin';
	/**
	 * The plugin zip file to install.
	 */
	pluginZipFile: ResourceType;
	/**
	 * Optional installation options.
	 */
	options?: InstallPluginOptions;
}

export interface InstallPluginOptions {
	/**
	 * Whether to activate the plugin after installing it.
	 */
	activate?: boolean;
}

/**
 * Installs a WordPress plugin in the Playground.
 * Technically, it uses the same plugin upload form as a WordPress user
 * would, and then activates the plugin if needed.
 *
 * @param playground The playground client.
 * @param pluginZipFile The plugin zip file.
 * @param options Optional. Set `activate` to false if you don't want to activate the plugin.
 */
export const installPlugin: StepHandler<InstallPluginStep<File>> = async (
	playground,
	{ pluginZipFile, options = {} },
	progress?
)

And then reuse it in multiple documents like:

  • Getting started with Blueprints
  • Blueprints as JSON
  • Blueprints as functions
# Getting started with Blueprints

... some content ...

You can install Gutenberg with the `installPlugin` step:

<LiveCodeSnippet>
   <BlueprintStepUsage step="installPlugin" />
</LiveCodeSnippet>
# Blueprints as JSON
... content...

### JSON steps

<BlueprintJSONStepsList />
# Blueprints as functions

... content...

### Functional Steps

<BlueprintFunctionsStepsList />

And get nicely formatted examples, live code snippets, and inline API docs in all three places. Furthermore, I want them to automatically reflect any changes in the code, e.g. newly committed Blueprint steps or any changes in the function signature.

Related: #217

@adamziel adamziel added [Type] Documentation Improvements or additions to documentation [Type] Enhancement New feature or request labels May 12, 2023
@adamziel
Copy link
Collaborator Author

adamziel commented May 13, 2023

Mdx could provide testable, interactive docs if they came with:

  • Code examples
  • Initialization scripts
  • Any fixtures required
  • Expected output

WordPress/Documentation-Issue-Tracker#730 (comment)

We could even put snippets in docstrings if the module-level docstring shipped runtime details. E.g:

/**
 * Runtime: Playground
 * Execution Script:
 * Import { startPlaygroundWeb, runBlueprint } from …
 * const client = await startPlaygroundWeb(…)
 */

/**
 * @example
 * > await loginStep(client);
 * > client.username
 * admin
 */
export function loginStep(client, ) {
   // …
}

@adamziel
Copy link
Collaborator Author

Docusaurus seems incredibly well suited for what Playground needs:

Importing components

Live code snippets could be embedded directly in the docs – how cool is that?!

Importing code snippets

You can not only import a file containing a component definition, but also import any code file as raw text, and then insert it in a code block, thanks to Webpack raw-loader. In order to use raw-loader, you first need to install it in your project

import CodeBlock from '@theme/CodeBlock';
import MyComponentSource from '!!raw-loader!./myComponent';

<CodeBlock language="jsx">{MyComponentSource}</CodeBlock>

Importing Markdown

You can use Markdown files as components and import them elsewhere, either in Markdown files or in React pages.

<span>Hello {props.name}</span>

This is text some content from `_markdown-partial-example.mdx`.
import PartialExample from './_markdown-partial-example.mdx';

<PartialExample name="Sebastien" />

@adamziel
Copy link
Collaborator Author

adamziel commented May 16, 2023

There's also support for:

  • Tabs (e.g. JSON / Functional Blueprint examples)
  • Interactive code editor – big YAY for JavaScript examples. I bet it could work with PHP and Interactivity API, too. CC @michalczaplinski
  • Strongly validated Markdown links. Goodbye broken links.
  • Mermaid Diagrams. Highly useful in a repo like this where a lot of concepts require visual aids.

There's even a plugin to grab Typedoc output

adamziel added a commit that referenced this issue May 21, 2023
Solves #323, related to #217.

# Description

This commit revisits the documentation site. Here's a preview:

https://wordpress.github.io/wordpress-playground/docs/blueprints-api/steps/

(I went ahead and deployed it to github.io even tough this PR isn't
merged yet since it's a much better entry point to the project).

## What changed?

This PR:

* Adds the missing bits of the documentation and improve the structure
* Adds the first interactive examples with more to come
* Generates parts of the docs directly from the doc strings
* Adds link validation
* Improves readability and interconnectedness between the content pages
and the API reference

It is the first step towards addressing the following issues with the
current documentation:

* It is incomplete
* It is not interactive
* It is not connected to code and a PR can make it go stale
* It is not testable and there's no way to know whether the code
snippets still work
* API docs can be hard to read
* Dead links – no link validation

## Technical details

* Docusaurus uses [MDX](https://mdxjs.com/) which is essentially
Markdown + React.
* TypeScript documentation is generated with Typedoc and included using
a Docusaurus plugin.
* Repeatable code snippets are abstracted to fragments. Updating them
once updates all the occurrences in the docs.
* We can use React components inside the mdx files. Super useful for
code examples and auto-displaying information derived from the
TypeScript code.

A few practical example of what's so good about this approach

### API Reference integration

<img width="600" alt="CleanShot 2023-05-21 at 14 07 17@2x"
src="https://github.com/WordPress/wordpress-playground/assets/205419/9a755d3c-e205-4b75-b3c4-bb0cd2bcd131">

### Runnable code examples

<img width="530" alt="CleanShot 2023-05-21 at 14 03 57@2x"
src="https://github.com/WordPress/wordpress-playground/assets/205419/466bb639-1bda-4303-9ce6-6a05eb234cab">
<img width="530" alt="CleanShot 2023-05-21 at 14 03 50@2x"
src="https://github.com/WordPress/wordpress-playground/assets/205419/c74916b3-0890-437e-beab-87b60b480fab">

### Reusable content

<img width="400" alt="CleanShot 2023-05-21 at 14 06 38@2x"
src="https://github.com/WordPress/wordpress-playground/assets/205419/78b3b7b1-042d-46c7-bfa4-c87f2f115d2e">
<img width="400" alt="CleanShot 2023-05-21 at 14 06 14@2x"
src="https://github.com/WordPress/wordpress-playground/assets/205419/b15d3238-5bca-47e1-bc2e-7ff31a58acc7">

### Inline TOC

<img width="300" alt="CleanShot 2023-05-21 at 14 05 14@2x"
src="https://github.com/WordPress/wordpress-playground/assets/205419/42a10f13-4f54-4a2c-bb5a-d9a66db85333">
<img width="300" alt="CleanShot 2023-05-21 at 14 05 35@2x"
src="https://github.com/WordPress/wordpress-playground/assets/205419/e5e374c7-d790-4c89-beb0-f064ccb8588c">

### Deriving Blueprint steps from code

With this PR, adding a Blueprint step into the codebase will
automatically add it to the docs. If it has a usage example, it will be
rendered as a live code snippet. In the future, it will be editable and
the CI will verify whether it still works.

<img width="441" alt="CleanShot 2023-05-21 at 01 23 22@2x"
src="https://github.com/WordPress/wordpress-playground/assets/205419/80b265f9-6954-45a1-bd35-e888fe3e5f91">

### Docusaurus prevents broken links

<img width="450" alt="CleanShot 2023-05-21 at 00 58 36@2x"
src="https://github.com/WordPress/wordpress-playground/assets/205419/b5e57360-9f2d-4676-9888-557c4c0bcf0c">

### TypeScript comment embedded inside of a documentation page

<img width="343" alt="CleanShot 2023-05-21 at 01 41 58@2x"
src="https://github.com/WordPress/wordpress-playground/assets/205419/c4cf1811-549e-4d21-ae8a-3009f8024b5a">

<img width="445" alt="CleanShot 2023-05-21 at 01 42 24@2x"
src="https://github.com/WordPress/wordpress-playground/assets/205419/5d6a9d5b-1286-466b-a082-fcdcc5659439">
@adamziel
Copy link
Collaborator Author

This is done as of #398

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Type] Documentation Improvements or additions to documentation [Type] Enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant