- LocalWP to.. run WP locally.
- Directory:
Local Sites\udemyreactblocks2023
- URL: udemyreactblocks2023.local/
- Directory:
- GH Repo
- Initially set to
Local Sites\udemyreactblocks2023\app\public\wp-content
- In order to capture changes to Plugins AND Theme modifications.
- Then new repos were created to handle the growing complexity as noted in the next section.
- Initially set to
- Section 1.01 ~ 1.08: Notes below
- Section 2.09 ~ 2.17: https://github.com/sr4136/udemy-react-blocks-2023/commits/
- Section 4.23 ~ 4.24: https://github.com/sr4136/udemy-react-blocks-boilerplate/commits/
- Section 4.26 ~ 4.39: https://github.com/sr4136/udemy-react-blocks-simple/commits/
- Section 5.43 ~ 5.74: https://github.com/sr4136/udemy-react-blocks-members/commits/
- Section 6.77 ~ 6.85: https://github.com/sr4136/udemy-react-blocks-dynamic/commits/
- Section 7.87 ~ 7.88: https://github.com/sr4136/udemy-react-blocks-plugin-boilerplate/commits/
- Section 8.90 ~ 8.91: https://github.com/sr4136/udemy-react-blocks-data-store/commits/
- Section 8.92 ~ 8.99: https://github.com/sr4136/udemy-react-blocks-plugin-datastore/commits and https://github.com/sr4136/udemy-react-blocks-data-store/commits/
- Section 9.100 ~ 9.105: https://github.com/sr4136/udemy-react-blocks-plugin-datastore/commits and https://github.com/sr4136/udemy-react-blocks-data-store/commits/
- Section 10.106: https://github.com/sr4136/udemy-react-blocks-members/commits/
- Section 10.107 ~ 10.113: https://github.com/sr4136/udemy-react-blocks-plugin-datastore/commits
1.4 - Concepts of what belongs where for a block in terms of content, modifiers/formatting, and other settings.
https://www.udemy.com/course/gutenberg/learn/lecture/27108642
1.5 - The representations of data/blocks/html.
https://www.udemy.com/course/gutenberg/learn/lecture/27108846
- #1 Editor Code View - the HTML that the blocks produce. SAVE Representation (Same ac #3)
- #2 Editor Visual View - the React Components (Complex) responsible for producing the HTMl. EDIT Representation
- #3 Frontend - the HTML that the blocks produce. SAVE Representation (Same as #1)
- React component (Complex) contains lots of data: what it should look like, what the toolbar and settings should contain.
- The PLAIN HTML is what is saved to the database & what gets called with the post's content().
- It's the React Component that takes that saved HTML and makes it editable again within its own context.
1.6 - How the Visual Editor is constructed from plain html.
https://www.udemy.com/course/gutenberg/learn/lecture/27108860
1.7 - A Brief Introduction to the Redux-like Data Stores in the Block Editor
https://www.udemy.com/course/gutenberg/learn/lecture/27108866
Use wp.data
to find the available data for the site.
-
wp.data.select("core/edit-post")
returns the data about the post editor. -
Instead of
select
,dispatch
can be used to run actions.wp.data.dispatch("core/edit-post").openGeneralSidebar("edit-post/block")
will open the sidebar to the Block tab.
-
wp.data.select("core")
will contain general info: sitewide authors, taxonomies, menus, site options, etc. -
wp.data.select("core/blocks").getBlockTypes()
will get all registered blocks for the site. -
wp.data.select("core/editor")
will contain info about the currently editing post.wp.data.select("core/editor").getBlocks()
is the Post State Array as in 1.6 above
-
Since the html blocks and comments are what is used to store ALL of the info about a block-- and then parsed for React/editing: when we create blocks, we define how to store/retrieve that data. Some of it is in the attributes comment, while the rest is extracted from the html. Ex:
-
get the image url from the
<img>
tag'ssrc
attribute. -
get the image's caption from the content of the
<figcaption>
element.
-
1.8 - The Post State Array in Action
https://www.udemy.com/course/gutenberg/learn/lecture/27108870
-
Parse: HTML -> Blocks.
-
Serialize: Blocks -> HTML.
-
We can use take the post's stored content (
wp.data.select("core/editor").getEditedPostContent()
) and pass it intowp.blocks.parse()
in order to generate the Post State Array as in 1.6 above.- This will MATCH what is produced by
wp.data.select("core/editor").getBlocks()
- This will MATCH what is produced by
-
Note: the word for the HTML comments that define a block are called
delimiters
- Inside a delimeter lives the HTML.
- These also contain an object with ID & other attributes.
-
The PARSER is what defines how to extract the attributes from the object AND the HTML content.
-
wp.blocks.serialize()
will take the Post State Array (or individual block objects) and turn them into -
More from the WP Docs
2.10 - Registering our First Block
- Plugin / plugin-entry-point.php file.
first-block/first-block.php
- Registers our block type using
register_block_type_from_metadata()
, which picks up on theblock.json
file we created with our block config. - uses
index.asset.php
which registers "wp-blocks" as an asset-- in a similar way that registering a dependancy viawp_enqueue
works. - More on
register_block_type_from_metadata()
andindex.asset.php
at the WP Docs on Dependency Management
2. 11 - Returning React Components in the Edit & Save Functions
- React without JSX
- WordPress Element provides an abstraction layer on top of React.
- Think of it as "jQuery~ifying" React. Standard abstraction layer regardless of how React changes beneath the hood. It omits "features with uncertain futures". And also ensures compatabilities between versions.
- 'wp-element' must be registered as a dependancy in order to use.
- So then we can use it to create elements:
-
var createElement = wp.element.createElement; return createElement( "p", null, "Edit" );
-
2.12 - Compiling ESNext to ES5 with wp-scripts
- Instead of
createElement
, we're going to use ESNext and a compiler. - We'll need to install
npm init
to initialize a newpackage.json
.npm install @wordpress/scripts --save-dev
for the WP Scripts.npm install @wordpress/blocks
so we can removevar registerBlockType = wp.blocks.registerBlockType;
and useimport { registerBlockType } from "@wordpress/blocks";
instead.
- Now, we can remove the
script.js
andindex.asset.php
in the root, as these will be auto-generated into the "build" directory upon runningnpx wp-scripts build
.- Also update
block.json
to swap to the neweditorScript
location inside of the "build" directory.
- Also update
- To watch the files for changes, instead of
npx wp-scripts build
, we can usenpx wp-scripts start
- Edit package.json. Add to "scripts" to add shortcuts:
-
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "wp-scripts build", "start": "wp-scripts start" }
npx wp-scripts build
->npm run build
npx wp-scripts start
->npm run start
-
- Because we use
import { registerBlockType } from "@wordpress/blocks";
within our block'sindex.js
, upon inspectingbuild/index.js
, it essentially comments out everything under the assumption that the globalwp
variable will be available in the browser. ~"It doesn't bundle it, but references it."
2.13 - Compiling & Loading SASS Files
- in
block.json
, you can pass astyle
param to load css in frontend AND editor.- and/or you can pass an
editorStyle
param that will load css in just the editor.
- and/or you can pass an
- Start getting "core" block properties: classes, attributes etc.
npm install @wordpress/block-editor
- add
import { useBlockProps } from "@wordpress/block-editor";
toblock.json
- use it within the edit/save functions:
const blockProps = useBlockProps();
- spread the variable within the block's output:
return <p {...blockProps}>Edit (w/ JSX)</p>
- for the save, we only need to FRONTEND props, so
const blockProps = useBlockProps.save();
- spread the variable within the block's output:
- Add a new file in
src
,style.scss
. wp-scripts will automatically compile this intobuild/style-index.css
.- Edit
block.json
to include CSS:"style": "file:./build/style-index.css",
Adds styles to the frontend and backend.
- Edit
- For the Editor-only style, add a file to
src
,editor.scss
. wp-scripts will automatically compile this intobuild/index.css
.- Edit
block.json
to include CSS:"editorStyle": "file:./build/index.css",
Adds styles to JUST the backend.
- Edit
Finally, move edit/save functions & sass into respective files. Export those functions in the files. Import them in the main index.js
.
- Ex at this commit
2.14 - Generating a Block with @wordpress/create-block
Now that we know the behind-the-scenes, we can automate most of this with wp-create-block
.
- In the
plugins
dir, runnpx @wordpress/create-block boilerplate
2.15 - Configuring ESLint & Prettier for JavaScript Files
- Install WP standards for eslint/prettier. Configure them with
.eslintrc
andpackage.json
.npm install @wordpress/eslint-plugin --save-dev
npm install eslint-config-prettier --save-dev
2.18 - Adding Custom Styles to the Block Editor
add_theme_support( "editor-styles" )
along withadd_editor_style( "style-editor.css" )
(or any other stylesheet) in order to load css for ONLY the backend block editor.- Adding styles to the
body
tag will get auto-transformed to the block editor's wrapper, which happens to be.editor-styles wrapper
.body { background-color: #ff0000; }
will become.editor-styles-wrapper { background-color: #ff0000; }
- Additional assumptions and transforms happen, for example:
.wp-block { max-width: 800px }
will become.editor-styles-wrapper .wp-block { max-width: 800px }
- Adding styles to the
add_theme_support( "responsive-embeds" )
to make embeds, like YT videos.. responsive.
2.19 - Adding Support for Align Wide and Align Full
add_theme_support( "align-wide" );
andadd_theme_support( "align-full" );
to get more alignment options for blocks that support it.- Some extra theme CSS would be required to make these look right, especially at certain breakpoints.
2.20 - Adding Custom Color Pallettes
-
add_theme_support( "editor-color-palette" );
will override the default color pallette with the supplied one.- There are ways to append to the default color palette as well.
- Corresponding CSS must be added for the frontend color classes.
- To remove the "custom color" (color picker) option from the pallette, you have to ADD theme support
add_theme_support( "disable-custom-colors" );
-
Similar overrides can be done for the gradients with modifying theme suppor for
editor-gradient-presets
.
2.22 - Custom Sizing & Custom Units
- adding theme support for
custom-spacing
enables padding/margin controls for blocks that support it- ...as well as other dimensions like min-height for covor blocks.
4.25 - Customizing the Block's Icon
- Instead of defining the block's icon with a dashicon in
block.json
, we can define it in viaindex.js
as a dashicon-- as well as background/foreground colors or pass in an SVG.-
in
registerBlockType()
:icon: { src: 'text-page', background: '#ff0000', foreground: '#ffffff', },
icon: ( <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <circle cx="50" cy="50" r="50" /> </svg> ),
-
And still can use bg/fg:
icon: { src: ( <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <circle cx="50" cy="50" r="50" /> </svg> ), background: '#00ff00', foreground: '#ffffff', },
-
4.28 - The AlignmentToolbar Component
- Separate out the onchange functions: https://github.com/sr4136/udemy-react-blocks-simple/blob/4768e7b67343e8bc1be042bb33db7f57cb0c873a/src/edit.js#L27-L33
- Add additional classes to components using
useBlockProps
: https://github.com/sr4136/udemy-react-blocks-simple/blob/4768e7b67343e8bc1be042bb33db7f57cb0c873a/src/edit.js#L49