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

Consider a scaffolding command dedicated to Gutenberg blocks #88

Closed
gziolo opened this issue Nov 8, 2017 · 19 comments

Comments

@gziolo
Copy link
Contributor

commented Nov 8, 2017

As the work on the new WordPress editor progresses, we thought that it would be great to simplify Gutenberg on-boarding process for plugin developers. It is still being discussed how native Gutenberg extensibility would look like, but we are confident that the most common use case will be that developers will want to create new blocks. We discussed it a bit already and it seems like the best way to start is to create a scaffolding command which creates a block registered into the editor that needs to have only logic updated. It would be great to have it included in the core of wp-cli.

Initial implementation

On the technical side, the only thing that is necessary to create a plugin that registers a new block is to provide two files similar to what @pento shared here:

https://gist.github.com/pento/19b35d621709042fc899e394a9387a54

Please note that this code doesn't use build step (no Webpack, Babel, etc.). It's only PHP and JavaScript code that will work out of the box. JS uses ES5 syntax that can run on every browser including IE11. It's a conscious decision to provide a default starter kit that produces code be approachable for developers coming from all possible backgrounds.

Side note: This sample code is a more advanced use case which uses post meta, which we can omit in the initial implementation.

Further iterations

We want to support also developers that want to use more advanced JavaScript tooling and we are happy to discuss how to provide more advanced tooling that would be enabled on demand things like:

  • build step (Webpack, Grunt, whatever)
  • code transpilation to allow ES.next syntax
  • linting
  • testing
  • etc.

It also raises the question if wp-cli would be able to install all dependencies listed in package.json and execute the build step behind the scenes.

Open questions

  1. We can also trigger a wider discussion if we want to move that tooling to a separate npm package to make them easier to reuse. I have also shared a blog post where I explain more in-depth advantages of starter kits and reusable scripts in the context of WordPress and Gutenberg.

  2. I already asked this question on Slack, but let me rephrase and ask again here. What do you think about the following flow for new developers:

    • wp scaffold plugin gutenberg (or something like that) using ssh to do it on the server the gutenberg plugin is being used on.
    • User goes to /wp-admin/plugin-editor.php page to edit the new plugin directly in the code editor bundled with WP and implements save and edit JavaScript methods for a newly bootstraped Gutenblock.
  3. Would it be possible to wrap wp-cli command with the interface exposed in Gutenberg, and create a new plugin that registers a block behind the scenes by filling in a form that mirrors CLI options?

@gziolo gziolo changed the title Consider adding scaffolding command dedicated to Gutenberg blocks Consider a scaffolding command dedicated to Gutenberg blocks Nov 8, 2017

@danielbachhuber

This comment has been minimized.

Copy link
Member

commented Nov 8, 2017

We discussed it a bit already and it seems like the best way to start is to create a scaffolding command which creates a block registered into the editor that needs to have only logic updated.

👍

We want to support also developers that want to use more advanced JavaScript tooling and we are happy to discuss how to provide more advanced tooling that would be enabled on demand things

I'm generally in support of this. We can discuss the specifics of the implementation along the way.

We can also trigger a wider discussion if we want to move that tooling to a separate npm package to make them easier to reuse.

If the scaffolded code was solely JavaScript, I think npm would make more sense. Given it's both PHP and JavaScript, with some additional value of being able to put the code in the right place, this WP-CLI package makes most sense to me.

I already asked this question on Slack, but let me rephrase and ask again here. What do you think about the following flow for new developers:

I'm on the fence as to whether this is a good idea. I don't fully understand the value, nor am I sure this is a reasonable expectation for usage. Open to further exploration though.

Would it be possible to wrap wp-cli command with the interface exposed in Gutenberg, and create a new plugin that registers a block behind the scenes by filling in a form that mirrors CLI options?

Potentially. If this is the direction you'd like to head, it might make more sense to create a standalone plugin that implements both a web interface and a WP-CLI command.

Personally though, I think the level of effort is low enough to add a wp scaffold block command to this repo and see what sort of uptick it gets.

@pento

This comment has been minimized.

Copy link
Member

commented Nov 9, 2017

I agree, wp scaffold block would be a super useful tool for getting people started with blocks.

@nb

This comment has been minimized.

Copy link
Contributor

commented Nov 9, 2017

👍 on having wp scaffold block, which does not require any npm interaction from the plugin author.

@gziolo

This comment has been minimized.

Copy link
Contributor Author

commented Nov 9, 2017

If the scaffolded code was solely JavaScript, I think npm would make more sense. Given it's both PHP and JavaScript, with some additional value of being able to put the code in the right place, this WP-CLI package makes most sense to me.

I was referring to the specific use case of JS scripts. At the moment wp scaffold plugin generates package.json that looks like this:

{
  "name": "gutenblock",
  "version": "0.1.0",
  "main": "Gruntfile.js",
  "author": "Gutenberg",
  "devDependencies": {
    "grunt": "~0.4.5",
    "grunt-wp-i18n": "~0.5.0",
    "grunt-wp-readme-to-markdown": "~1.0.0"
  }
}

Grunt exposes two tasks: i18n and readme. The idea behind reusable scripts is to put all those 3 dependencies in their own package called let's say wp-scripts and expose those scripts as executable files. So package.json would look this way:

{
  "name": "gutenblock",
  "version": "0.1.0",
  "author": "Gutenberg",
  "devDependencies": {
    "wp-scripts": "~0.1.0",
  },
  "scripts": {
    "i18n": "wp-scripts i18n",
    "readme": "wp-scripts readme",
  }
}

There are a few advantages of this approach:

  • You have only one dependency to update whenever scripts change.
  • You can always check package.json to see what command are available.
  • You don't need to know Grunt to execute npm run i18n or npm run readme.
  • You can easily upgrade from Grunt to Gulp or whatever comes next.

This becomes even more useful when you introduce new scripts and have dozens of plugins to update.

More advanced example from the article Tools without config by @kentcdodds:

0-rsrntuowyunpltpk

@gziolo

This comment has been minimized.

Copy link
Contributor Author

commented Nov 9, 2017

👍 on having wp scaffold block, which does not require any npm interaction from the plugin author.

Yes, this is what I'd like to start with and then we can discuss further steps.

@danielbachhuber, what would be your advice on the technical level on how to tackle this new command? It looks like it could a slightly modified version of wp scaffold plugin. Based on the existing implementation found here, I think it boils down to having a bit customized code around creating files and providing new templates. In simplified version it would be sth along those lines:

$files_written = $this->create_files( array(
-	$plugin_path => self::mustache_render( 'plugin.mustache', $data ),
+	$plugin_path => self::mustache_render( 'plugin-block.mustache', $data ),
	$plugin_readme_path => self::mustache_render( 'plugin-readme.mustache', $data ),
	"$plugin_dir/package.json" => self::mustache_render( 'plugin-packages.mustache', $data ),
+	"$plugin_dir/$plugin_slug.js" => self::mustache_render( 'plugin-block-js.mustache', $data ),
	"$plugin_dir/Gruntfile.js" => self::mustache_render( 'plugin-gruntfile.mustache', $data ),
	"$plugin_dir/.gitignore" => self::mustache_render( 'plugin-gitignore.mustache', $data ),
	"$plugin_dir/.distignore" => self::mustache_render( 'plugin-distignore.mustache', $data ),
	"$plugin_dir/.editorconfig" => file_get_contents( self::get_template_path( '.editorconfig' ) ),
), $force );
@danielbachhuber

This comment has been minimized.

Copy link
Member

commented Nov 9, 2017

what would be your advice on the technical level on how to tackle this new command? It looks like it could a slightly modified version of wp scaffold plugin.

I think we'd want something closer to wp scaffold post-type. The command would implement a few configuration options, as well as --theme (to create the files within the active theme directory) and --plugin=<plugin> (to create the files within a given plugin directory).

Generally, the behaviors should be similar to wp scaffold post-type. I'd suggest playing around with that command a bit to see what the UX is like.

I think it boils down to having a bit customized code around creating files and providing new templates.

Correct. At a high-level, you'll need to implement your base block code as one or more mustache templates. The command's responsibility is to populate the templates and then create files with the template content.

@gziolo

This comment has been minimized.

Copy link
Contributor Author

commented Nov 10, 2017

@danielbachhuber many thanks for your great hints, it makes perfect sense to have wp scaffold block --plugin=<plugin>.

My last 2 questions (for now 😄 ):

  • Is it an acceptable behavior to auto-create plugin if doesn't exist.
  • Does wp-cli offer interactive mode similar to what inquirer offers for node developers? See:
    inquirer
    screenshot
@nerrad

This comment has been minimized.

Copy link

commented Nov 10, 2017

wp {command} --prompt might be what you are thinking of. If I remember correctly, when users use --prompt in executing the command, that will prompt for values for each defined command argument.

@danielbachhuber

This comment has been minimized.

Copy link
Member

commented Nov 10, 2017

Is it an acceptable behavior to auto-create plugin if doesn't exist.

Nope. Commands are expected to be orthogonal. However, we can include block scaffolding as a default behavior of wp scaffold plugin.

@gziolo

This comment has been minimized.

Copy link
Contributor Author

commented Nov 10, 2017

wp {command} --prompt might be what you are thinking of. If I remember correctly, when users use --prompt in executing the command, that will prompt for values for each defined command argument.

@nerrad, this is exactly what I was looking for. Yes, wp scaffold plugin --prompt asks you to provide values for all options 👍

Nope. Commands are expected to be orthogonal. However, we can include block scaffolding as a default behavior of wp scaffold plugin.

@danielbachhuber I will code it with the assumption that plugin is already there. Let's circle back to this once it's done. Thanks again 💯

@danielbachhuber

This comment has been minimized.

Copy link
Member

commented Nov 10, 2017

@gziolo As a total aside, that inquirer library looks really cool.

@gziolo

This comment has been minimized.

Copy link
Contributor Author

commented Nov 20, 2017

@danielbachhuber, can you assign me to this one? I'll work on it this week. I'll open a PR tomorrow.

@danielbachhuber

This comment has been minimized.

Copy link
Member

commented Nov 28, 2017

@gziolo I've tagged v1.1.0 of scaffold-command so we can land the initial imlpementation in wp cli update --nightly


From your PR:

In the follow-up PR we can cover more advanced examples like a dynamic block or server-side rendered block using Post meta.

This would be a very helpful next step, I think. In reading through the scaffolded code to understand it (not solely review for code quality), my immediate thought was: "how do I update my existing shortcode to work like a block?"

@gziolo

This comment has been minimized.

Copy link
Contributor Author

commented Nov 28, 2017

I've tagged v1.1.0 of scaffold-command so we can land the initial imlpementation in wp cli update --nightly

Does it mean it will be available in the latest version of wp-cli as of tomorrow?

This would be a very helpful next step, I think. In reading through the scaffolded code to understand it (not solely review for code quality), my immediate thought was: "how do I update my existing shortcode to work like a block?"

Yes, let's do it as part of the issue you just created. I need to find out what advanced examples are out there :)

Should we close this issue?

@gziolo

This comment has been minimized.

Copy link
Contributor Author

commented Nov 28, 2017

Ah, this was for Gutenberg, I will start another PR probably next week. Thank for your amazing help @danielbachhuber 💯

@danielbachhuber

This comment has been minimized.

Copy link
Member

commented Nov 28, 2017

Does it mean it will be available in the latest version of wp-cli as of tomorrow?

Nightly build is a bit of a misnomer. It's available now :) I've put out a call for feedback too.

@danielbachhuber

This comment has been minimized.

Copy link
Member

commented Nov 28, 2017

Another idea to throw into the mix: Add jsDoc to the scaffolded edit and save functions that provides an introductory overview to the functions and then links to the corresponding handbook docs.

@schlessera

This comment has been minimized.

Copy link
Member

commented Dec 29, 2017

First implementation, together with extensive inline documentation, has been completed.

@schlessera schlessera closed this Dec 29, 2017

@gziolo

This comment has been minimized.

Copy link
Contributor Author

commented Dec 29, 2017

In the follow-up PR we can cover more advanced examples like a dynamic block or server-side rendered block using Post meta.
This would be a very helpful next step, I think. In reading through the scaffolded code to understand it (not solely review for code quality), my immediate thought was: "how do I update my existing shortcode to work like a block?"

I plan to add --template flag with 2 more JS templates in the upcoming weeks. Hopefully on time for v1.5 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.