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

Introduce Playground Blueprints to create, mix, and share specific Playground setups #201

Closed
adamziel opened this issue Apr 13, 2023 · 6 comments

Comments

@adamziel
Copy link
Collaborator

adamziel commented Apr 13, 2023

Public JavaScript API doesn't cut it

I want to easily share links to very specific Playground builds.

For example, to GlotPress Playground. Right now it's an app that imperatively installs a GlotPress plugin, set up some wp_options, submit a few forms to set it up, installs another plugin to translate, and then redirects to a correct landing page in wp-admin. I'd like to be able to express all that using a single config. I could then a URL to Playground using that config.

Playground's public JavaScript API is great, but it depends on JavaScript which is not sandboxed and thus not easily portable. For example, it wouldn't be wise to allow plugin authors to run arbitrary JavaScript to set up a preview in the WordPress.org plugin directory.

Let's find a declarative, portable, composable blueprint format

Imagine Playground was configured declaratively:

{
    "theme": "pendant",
    "plugins": [ "glotpress", "activitypub", "https://mysite.com/custom-plugin.zip" ],
    "data": {
        "options": {
            "WPLANG": "de",
            "permalink_structure": "/%year%/%monthnum%/%day%/%postname%/"
        },
        "posts": [
            { "title": "My first post", ... }
        ],
    }
    "actions": [
        { 
            "type": "request",
            "url": "/wp-admin/setup-something.php",
            "method": "POST",
            "formData": { }
        },
        { 
            "type": "callback",
            "php_function": "setup_glotpress"
        },
        {
            "type": "redirect",
            "target": "/wp-admin/"
        }
    ]
}

The data format could be JSON but another interesting idea is PHP header comment:

/**
 * Plugins: gutenberg, activitypub
 */

WordPress Playground could then use that config as a blueprint for the environment.

But what about things that can't be expressed in JSON?

A PHP callback could be used to produce that JSON dynamically:

function local_glotpress_blueprint() {
    return [
       "plugins": [ "glotpress", $custom_plugin ],
       // ...
    ];
}

Composability

Multiple blueprints could be used together e.g. to set up a Playground with GlotPress, WooCommerce, and a specific set of content.

Relation to importing

Are Blueprints and export files one and the same?

Playground Blueprint includes many of the same information as an export file would, like posts, plugins, wp_options. For more involved setups, a blueprint could say something like { "exportFile": "./export.zip" } and automatically trigger an import. These imports would have to be composable, which means no wiping out the database upfront.

What would then a blueprint have that an export would have not? For sure the convenience of writing a JSON or a PHP file by hand. What else?

Challenges

  • WP importer is very limited and doesn’t handle users, site options, custom db tables
  • Composing two and more files requires resolving ID conflicts and remapping foreign keys
  • User passwords, I think, depend on the hardcoded WP secret

The plan

The following plan would provide some value with relatively little effort:

  • Support importing from WXR and WXZ for "easy" use-cases
  • Potentially support setting some basic information like site options with Blueprint JSON
  • Support running custom PHP code to tackle more advanced use-cases
  • Support importing an entire zipped site

Version 1 would offer no composability and no automated way of exporting the existing playground instance into any format but the entire site zipped. This way extenders could use their existing export data while also having a way to tweak anything that isn't quite right. CC @bengreeley

Related issues

@adamziel adamziel changed the title Shared Configuration Format Introduce Playground Blueprints to create, mix, and share specific Playground setups Apr 13, 2023
@adamziel
Copy link
Collaborator Author

adamziel commented Apr 13, 2023

Another related issue – VSCode extension could really use a .wp-playground.json file indicating stuff like what is a plugin, what is core, what is mu-plugin (to quote @dmsnell).

@adamziel
Copy link
Collaborator Author

@bengreeley noted that if we can somehow make it compatible with the existing starter content that was discussed here that would be a win too

@adamziel
Copy link
Collaborator Author

With blueprints, you could „host” actual WordPress sites using Playground.

@dmsnell
Copy link
Member

dmsnell commented Apr 17, 2023

the actions have some clearly specific intentions like "install this plugin from the registry" but I also wonder how quickly it turns into something where we would want to run PHP anyway.

could there be an easy way to have a PHP boot script where all this can be done with familiar tools? or do you think there's a higher need to abstract those actions into a new language of terms and sequencing and support?

for example, when we get to the point where we want to create a specific user with specific posts do we build a declarative syntax for that, require an import file, or allow people to do whatever by calling PHP code that would run within the WP context

@adamziel
Copy link
Collaborator Author

adamziel commented Apr 21, 2023

You're right @dmsnell and I don't want to create a meta-language. Blueprint won't have ifs, loops, or variables. Blueprints provide a limited and well-defined set of features and if you need anything beyond that, it's time to write some JS or PHP.

The first version of Blueprints I merged in #211 enable custom PHP boot scripts via the runPHP step:

{
   "steps": [
      { "step": "runPHP", "code": "<?php require '/wordpress/wp-load.php'; /* do anything */ "}
   ]
}

We'll soon find out if that's be a common enough use-case to warrant some kind of shorthand syntax.

@adamziel
Copy link
Collaborator Author

This is already implemented so let's close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants