Skip to content

Commit

Permalink
Add new block development "Quick Start Guide" and update the `create-…
Browse files Browse the repository at this point in the history
…block-tutorial-template` (#56056)

* Add the new quick start guide.

* Update the create-block tutorial template to work with the new quick start guide.

* Remove the quick start guide from the create block tutorial.

* Add back ABSPATH check.

* Revert change to package version number.

* Update readme.

* Remove @wordpress/icons dependency and add custom icon.

* Fix title in manifest.

* Fix heading in Quick Start Guide.
  • Loading branch information
ndiego authored Nov 13, 2023
1 parent e2204ea commit 8ecddc9
Show file tree
Hide file tree
Showing 17 changed files with 233 additions and 123 deletions.
18 changes: 0 additions & 18 deletions docs/getting-started/create-block/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,6 @@ The tutorial includes setting up your development environment, tools, and gettin

The first thing you need is a development environment and tools. This includes setting up your WordPress environment, Node, NPM, and your code editor. If you need help, see the [setting up your development environment documentation](/docs/getting-started/devenv/README.md).

## Quick Start

The `@wordpress/create-block` package exists to create the necessary block scaffolding to get you started. See [create-block package documentation](https://www.npmjs.com/package/@wordpress/create-block) for additional features. This quick start assumes you have a development environment with node installed, and a WordPress site.

From your plugins directory, to create your block run:

```sh
npx @wordpress/create-block gutenpride --template @wordpress/create-block-tutorial-template
```

> Remember that you should use Node.js v14. Other versions may result in an error in the terminal. See [Node Development Tools](https://developer.wordpress.org/block-editor/getting-started/devenv/#node-development-tools) for more info.
The [npx command](https://docs.npmjs.com/cli/v8/commands/npx) runs a command from a remote package, in this case our create-block package that will create a new directory called `gutenpride`, installs the necessary files, and builds the block plugin. If you want an interactive mode that prompts you for details, run the command without the `gutenpride` name.

You now need to activate the plugin from inside wp-admin plugins page.

After activation, go to the block editor and use the inserter to search and add your new block.

## Table of Contents

The create a block tutorials breaks down to the following sections.
Expand Down
44 changes: 44 additions & 0 deletions docs/getting-started/quick-start-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Quick Start Guide

This guide is designed to demonstrate the basic principles of block development in WordPress using a hands-on approach. Following the steps below, you will create a custom block plugin that uses modern JavaScript (ESNext and JSX) in a matter of minutes. The example block displays the copyright symbol (©) and the current year, the perfect addition to any website's footer.

## Scaffold the block plugin

Start by ensuring you have Node.js and `npm` installed on your computer. Review the [Node.js development environment](https://developer.wordpress.org/block-editor/getting-started/devenv/nodejs-development-environment/) guide if not.

Next, use the [`@wordpress/create-block`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-create-block/) package and the [`@wordpress/create-block-tutorial-template`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-create-block-tutorial-template/) template to scaffold the complete “Copyright Date Block” plugin.

<div class="callout callout-info">
<p>You can use <code>create-block</code> to scaffold a block just about anywhere and then use <a href="https://developer.wordpress.org/block-editor/getting-started/devenv/get-started-with-wp-env/"><code>wp-env</code></a> inside the generated plugin folder. This will create a local WordPress development environment with your new block plugin installed and activated.</p>
<p>If you already have your own <a href="https://developer.wordpress.org/block-editor/getting-started/devenv/#local-wordpress-environment">local WordPress development environment</a>, navigate to the <code>plugins/</code> folder using the terminal.</p>
</div>

Choose the folder where you want to create the plugin, and then execute the following command in the terminal from within that folder:

```sh
npx @wordpress/create-block copyright-date-block --template create-block-tutorial-template
```

The `slug` provided (`copyright-date-block`) defines the folder name for the scaffolded plugin and the internal block name.

Navigate to the Plugins page of your local WordPress installation and activate the “Copyright Date Block” plugin. The example block will then be available in the Editor.

## Basic usage

With the plugin activated, you can explore how the block works. Use the following command to move into the newly created plugin folder and start the development process.

```sh
cd copyright-date-block && npm start
```

When `create-block` scaffolds the block, it installs `wp-scripts` and adds the most common scripts to the block’s `package.json` file. Refer to the [Get started with wp-scripts](https://developer.wordpress.org/block-editor/getting-started/devenv/get-started-with-wp-scripts/) article for an introduction to this package.

The `npm start` command will start a development server and watch for changes in the block’s code, rebuilding the block whenever modifications are made.

When you are finished making changes, run the `npm run build` command. This optimizes the block code and makes it production-ready.

## Additional resources

- [Get started with create-block](https://developer.wordpress.org/block-editor/getting-started/devenv/get-started-with-create-block/)
- [Get started with wp-scripts](https://developer.wordpress.org/block-editor/getting-started/devenv/get-started-with-wp-scripts/)
- [Get started with wp-env](https://developer.wordpress.org/block-editor/getting-started/devenv/get-started-with-wp-env/)
6 changes: 6 additions & 0 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@
"markdown_source": "../docs/getting-started/devenv/get-started-with-wp-scripts.md",
"parent": "devenv"
},
{
"title": "Quick Start Guide",
"slug": "quick-start-guide",
"markdown_source": "../docs/getting-started/quick-start-guide.md",
"parent": "getting-started"
},
{
"title": "Create a Block Tutorial",
"slug": "create-block",
Expand Down
1 change: 1 addition & 0 deletions docs/toc.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
}
]
},
{ "docs/getting-started/quick-start-guide.md": [] },
{
"docs/getting-started/create-block/README.md": [
{
Expand Down
4 changes: 4 additions & 0 deletions packages/create-block-tutorial-template/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Breaking Change

- Update the block example scaffolded by the template.

## 2.33.0 (2023-11-02)

## 2.32.0 (2023-10-18)
Expand Down
4 changes: 3 additions & 1 deletion packages/create-block-tutorial-template/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Create Block Tutorial Template

This is a template for [`@wordpress/create-block`](https://github.com/WordPress/gutenberg/tree/HEAD/packages/create-block/README.md) that is the finished version of the block in the official [WordPress Tutorial](https://github.com/WordPress/gutenberg/tree/HEAD/docs/getting-started/create-block/README.md) for the block editor.
This is a template for [`@wordpress/create-block`](https://github.com/WordPress/gutenberg/tree/HEAD/packages/create-block/README.md) that creates an example "Copyright Date" block. This block is used in the official WordPress block development [Quick Start Guide](https://developer.wordpress.org/block-editor/getting-started/quick-start-guide).

## Usage

Expand All @@ -10,6 +10,8 @@ This block template can be used by running the following command:
npx @wordpress/create-block --template @wordpress/create-block-tutorial-template
```

Use the default options when prompted in the terminal.

## Contributing to this package

This is an individual package that's part of the Gutenberg project. The project is organized as a monorepo. It's made up of multiple self-contained software packages, each with a specific purpose. The packages in this monorepo are published to [npm](https://www.npmjs.com/) and used by [WordPress](https://make.wordpress.org/core/) as well as other software projects.
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,17 +1,40 @@
/**
* WordPress components that create the necessary UI elements for the block
* Retrieves the translation of text.
*
* @see https://developer.wordpress.org/block-editor/packages/packages-components/
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-i18n/
*/
import { TextControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
* React hook that is used to mark the block wrapper element.
* It provides all the necessary props like the class name.
* Imports the InspectorControls component, which is used to wrap
* the block's custom controls that will appear in in the Settings
* Sidebar when the block is selected.
*
* Also imports the React hook that is used to mark the block wrapper
* element. It provides all the necessary props like the class name.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-block-editor/#inspectorcontrols
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-block-editor/#useblockprops
*/
import { useBlockProps } from '@wordpress/block-editor';
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';

/**
* Imports the necessary components that will be used to create
* the user interface for the block's settings.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/components/panel/#panelbody
* @see https://developer.wordpress.org/block-editor/reference-guides/components/text-control/
* @see https://developer.wordpress.org/block-editor/reference-guides/components/toggle-control/
*/
import { PanelBody, TextControl, ToggleControl } from '@wordpress/components';

/**
* Imports the useEffect React Hook. This is used to set an attribute when the
* block is loaded in the Editor.
*
* @see https://react.dev/reference/react/useEffect
*/
import { useEffect } from 'react';

/**
* The edit function describes the structure of your block in the context of the
Expand All @@ -26,13 +49,59 @@ import { useBlockProps } from '@wordpress/block-editor';
* @return {Element} Element to render.
*/
export default function Edit( { attributes, setAttributes } ) {
const blockProps = useBlockProps();
const { fallbackCurrentYear, showStartingYear, startingYear } = attributes;

// Get the current year and make sure it's a string.
const currentYear = new Date().getFullYear().toString();

// When the block loads, set the fallbackCurrentYear attribute to the
// current year if it's not already set.
useEffect( () => {
if ( currentYear !== fallbackCurrentYear ) {
setAttributes( { fallbackCurrentYear: currentYear } );
}
}, [ currentYear, fallbackCurrentYear, setAttributes ] );

let displayDate;

// Display the starting year as well if supplied by the user.
if ( showStartingYear && startingYear ) {
displayDate = startingYear + '' + currentYear;
} else {
displayDate = currentYear;
}

return (
<div { ...blockProps }>
<TextControl
value={ attributes.message }
onChange={ ( val ) => setAttributes( { message: val } ) }
/>
</div>
<>
<InspectorControls>
<PanelBody title={ __( 'Settings', '{{textdomain}}' ) }>
<ToggleControl
checked={ showStartingYear }
label={ __(
'Show starting year',
'{{textdomain}}'
) }
onChange={ () =>
setAttributes( {
showStartingYear: ! showStartingYear,
} )
}
/>
{ showStartingYear && (
<TextControl
label={ __(
'Starting year',
'{{textdomain}}'
) }
value={ startingYear }
onChange={ ( value ) =>
setAttributes( { startingYear: value } )
}
/>
) }
</PanelBody>
</InspectorControls>
<p { ...useBlockProps() }{ displayDate }</p>
</>
);
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,49 +5,41 @@
*/
import { registerBlockType } from '@wordpress/blocks';

/**
* Lets webpack process CSS, SASS or SCSS files referenced in JavaScript files.
* All files containing `style` keyword are bundled together. The code used
* gets applied both to the front of your site and to the editor. All other files
* get applied to the editor only.
*
* @see https://www.npmjs.com/package/@wordpress/scripts#using-css
*/
import './style.scss';
import './editor.scss';

/**
* Internal dependencies
*/
import Edit from './edit';
{{#isStaticVariant}}
import save from './save';
{{/isStaticVariant}}
import metadata from './block.json';

/**
* Define a custom SVG icon for the block. This icon will appear in
* the Inserter and when the user selects the block in the Editor.
*/
const calendarIcon = (
<svg
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
focusable="false"
>
<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm.5 16c0 .3-.2.5-.5.5H5c-.3 0-.5-.2-.5-.5V7h15v12zM9 10H7v2h2v-2zm0 4H7v2h2v-2zm4-4h-2v2h2v-2zm4 0h-2v2h2v-2zm-4 4h-2v2h2v-2zm4 0h-2v2h2v-2z"></path>
</svg>
);

/**
* Every block starts by registering a new block type definition.
*
* @see https://developer.wordpress.org/block-editor/developers/block-api/#registering-a-block
*/
registerBlockType( metadata.name, {
/**
* Used to construct a preview for the block to be shown in the block inserter.
*/
example: {
attributes: {
message: '{{title}}',
},
},
icon: calendarIcon,
/**
* @see ./edit.js
*/
edit: Edit,
{{#isStaticVariant}}

/**
* @see ./save.js
*/
save,
{{/isStaticVariant}}
} );
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
{{#isDynamicVariant}}
<?php
/**
* PHP file to use when rendering the block type on the server to show on the front end.
*
* The following variables are exposed to the file:
* $attributes (array): The block attributes.
* $content (string): The block default content.
* $block (WP_Block): The block instance.
*
* @see https://github.com/WordPress/gutenberg/blob/trunk/docs/reference-guides/block-api/block-metadata.md#render
*/
?>
<p <?php echo get_block_wrapper_attributes(); ?>>
<?php echo esc_html( $attributes['message'] ); ?>
</p>
{{/isDynamicVariant}}

// Get the current year.
$current_year = date( "Y" );

// Determine which content to display.
if ( isset( $attributes['fallbackCurrentYear'] ) && $attributes['fallbackCurrentYear'] === $current_year ) {
// The current year is the same as the fallback, so use the block content saved in the database (by the save.js function).
$block_content = $content;
} else {
// The current year is different from the fallback, so render the updated block content.
if ( ! empty( $attributes['startingYear'] ) && ! empty( $attributes['showStartingYear'] ) ) {
$display_date = $attributes['startingYear'] . '' . $current_year;
} else {
$display_date = $current_year;
}

$block_content = '<p ' . get_block_wrapper_attributes() . '>© ' . esc_html( $display_date ) . '</p>';
}

echo wp_kses_post( $block_content );
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{{#isStaticVariant}}
/**
* React hook that is used to mark the block wrapper element.
* It provides all the necessary props like the class name.
Expand All @@ -16,10 +15,27 @@ import { useBlockProps } from '@wordpress/block-editor';
*
* @param {Object} props Properties passed to the function.
* @param {Object} props.attributes Available block attributes.
*
* @return {Element} Element to render.
*/
export default function save( { attributes } ) {
const blockProps = useBlockProps.save();
return <div { ...blockProps }>{ attributes.message }</div>;
const { fallbackCurrentYear, showStartingYear, startingYear } = attributes;

// If there is no fallbackCurrentYear, which could happen if the block
// is loaded from a template/pattern, return null. In this case, block
// rendering will be handled by the render.php file.
if ( ! fallbackCurrentYear ) {
return null;
}

let displayDate;

// Display the starting year as well if supplied by the user.
if ( showStartingYear && startingYear ) {
displayDate = startingYear + '' + fallbackCurrentYear;
} else {
displayDate = fallbackCurrentYear;
}

return <p { ...useBlockProps.save() }{ displayDate }</p>;
}
{{/isStaticVariant}}
Loading

0 comments on commit 8ecddc9

Please sign in to comment.