Learn icon indicating copy to clipboard operation
Learn copied to clipboard

Course: Block Development

Open westnz opened this issue 3 years ago • 45 comments

westnz avatar Jun 03 '22 09:06 westnz

Michael Burridge is working on this course and I will be supporting him along the way as Instructional Designer. Here is the initial planning doc: Block Development Course Objectives

westnz avatar Jun 03 '22 09:06 westnz

Thanks Wes.

mburridge avatar Jun 03 '22 10:06 mburridge

Michael Burridge is working on this course and I will be supporting him along the way as Instructional Designer. Here is the initial planning doc: Block Development Course Objectives

Hi, @westnz that link requires access. Can we make it read-only for public view?

azhiya avatar Jun 03 '22 10:06 azhiya

Thank you @azhiya Michael changed the access to read-only for public view.

westnz avatar Jun 03 '22 11:06 westnz

Discussed in Slack: https://wordpress.slack.com/archives/C02RW657Q/p1654255617979579

azhiya avatar Jun 03 '22 12:06 azhiya

COURSE UPDATE

Michael has started building the course in Sensei:

The outline is complete and he has drafted the Introduction and Module 1.

Herewith my feedback so far and recent discussions we have had:

Feedback – Introduction & Getting started module - Wes Thank you for the wonderful work you have started here. Herewith is some feedback from an educational point of view:

Introduction I absolutely love how you have laid out the learning journey in the introduction. Students exactly know what to expect, and what they will be learning, and creating. You highlight the progressive sequence of lessons clearly. My only suggestion is to use some bullet points when you mention “So, what will you be building in this course?” to break up the number of paragraphs and highlight it.

What is a block? Short and sweet. I think we need to look at how to add visually appealing features – here and throughout the course.

I would also suggest using the following blocks to highlight/summarize/emphasize certain points or concepts going forward: Info Callout, Tip Callout and Alert Callout. I noticed you have used the Tip Callout in the Build and run a project lesson. 😃

Set up your development environment Thorough list!

<should we give instructions for this? Docker is needed.> Yes, I think so <should we provide instructions on installing these?> Yes <should we cover using nvm to manage node/npm versions?> I think it is better to cover all our bases.

You mentioned; “Additionally you should know, or be prepared to learn, the basics of React.” Could you add links to more resources for those who are not well-acquainted with React?

Scaffold your first block The conversational style of writing and the way lessons have been broken into digestible pieces are effective.

I want to pause here and think about how we can engage learners throughout the course by using some techniques like using visuals, storytelling, examples of before and after, compelling dilemmas or asking interesting questions.

Understand the structure of the project You are really good at explaining things and structuring things in a logical and sequential order. Maybe we could use a Tip Callout to highlight the directories that will probably never be touched.

The video that we will be creating will be helpful here to go through the src directory. Adding too many images here will lead to cognitive overload.

Build and run your project This page flows very well visually for me. 👍️

Make some simple changes I assume this is still being worked on.

Michael's response:

Hey Wes, thanks so much for casting an eye over the course as it exists thus far, and for your in-depth comments.

Introduction

My only suggestion is to use some bullet points when you mention “So, what will you be building in this course?”

TBH I think I’d prefer the introduction to have a more conversational flow and a more engaging style.

What is a block?

I think we need to look at how to add visually appealing features

I would also suggest using the following blocks to highlight/summarize/emphasize certain points or concepts going forward

I agree with these points, I’ll revisit this (and probably many other lessons) later on when I’ve got the bulk of the content done to add refinements such as the ones you suggest here. For now I want to get a first draft done that can be revised and iterated on.

Set up your development environment

Could you add links to more resources for those who are not well-acquainted with React?

Done!

Regarding my questions, which you answered in the affirmative, my doubts are about overloading the learner with peripheral information that can be obtained elsewhere. Should we go for “completeness” or keep things tightly focussed on the subject matter we’re addressing?

Scaffold your first block

I want to pause here and think about how we can engage learners throughout the course by using some techniques like using visuals, storytelling, examples of before and after, compelling dilemmas or asking interesting questions.

Great points. Again something that can be addressed when I come to revise the content. For now I’m going to focus on getting as much content in as possible.

Understand the structure of the project

Maybe we could use a Tip Callout to highlight the directories that will probably never be touched.

Good idea. I’ll bear in mind ways in which I can make the content more visually appealing and more easily digestible once I’ve got the first draft down.

For now I’ve changed it to use bullet points just to break up the “monolithic block of text” look.

Make some simple changes I assume this is still being worked on.

Yup. 😄

Thanks again for giving it the once over Wes, and thanks too for your kind remarks. I’ll bear all your points in mind as I work on future lessons. I guess I’m more or less on the right track so for now I’ll just keep on keeping on.

Wes's feedback:

Absolutely! You are more than on the right track and it makes a lot of sense coming back to add refinements etc.

my doubts are about overloading the learner with peripheral information that can be obtained elsewhere. Should we go for “completeness” or keep things tightly focussed on the subject matter we’re addressing?

Good point. Maybe you could just add the info as a footer at the end of the lesson if you wish to. Something like this:

westnz avatar Jul 13 '22 00:07 westnz

Update: Michael has now added content to module 2. He hopes to have the text-based part of the course finished by the end of August. 🤞

westnz avatar Aug 03 '22 23:08 westnz

Update: work done in the past two weeks (08 Aug 2022 - 19 Aug 2022)

I encountered a couple of minor bugs in the project as I reconstructed the project for the purposes of creating the course. They were mainly me making coding errors, but they still took a bit of time to track down.

The target for this period was to finish the four lessons that would complete the course up to the end of module 4. The course structure is continually being modified as the content develops and two new lessons were added. I therefore haven’t completed up to the end of module 4 as planned, so the target was not met in that sense, but I did complete four lessons.

The lesson "Conditionally display controls" has been moved to later in the course.

Achievements in this period

  • Resolved some bugs in the project

  • I had a pair-programming session with Ryan in which we finally got the custom NumberControl block working properly – although I did already have a working version there was an annoying interface bug when the user typed directly into the input element instead of using the spinner controls

  • As a result of finally having a fully working version I incorporated the custom NumberControl block into the course – it has been presented in the course as a snippet for the learner to simply copy and paste. How to create a custom component will be reserved for a separate course.

  • Did some more restructuring of the course – two new lessons added:

  • Completed four lessons:

mburridge avatar Aug 22 '22 09:08 mburridge

Thank you @mburridge. You sure have put a lot of work into this so far! Well done!!

westnz avatar Aug 22 '22 23:08 westnz

The draft of the Block Development Course is now ready for review. :tada:

Please provide your feedback as a comment here by Thursday, 15 September.

Here's some things to take into account during your review of the course:

  • check for technical accuracy, i.e. have I described or explained something wrongly or used any technical terms wrongly or inappropriately?
  • check the technical explanations and suggest ways of explaining things better or more clearly
  • build the project step by step and ensure that the code works at each step
    • is there a better way to implement any of the code, e.g. more efficient, more accepted, fits better with “best practice”?
  • evaluate whether the course is suitably progressive:
    • that it starts with simple concepts and gradually introduces more complicated concepts
    • no technical concepts are suddenly introduced without previous explanation or out of context
    • that there are no sudden conceptual leaps
    • that the learner is not left confused at any point
  • check that the course is suitably comprehensive, i.e. major concepts needed for learners getting started with block development are all covered
    • yet not overly so, i.e. no unnecessary or over-complicated concepts are introduced that are not suitable for this level of learner
  • grammar and spelling check, i.e. text is clear and there are no typos
  • evaluate the structure of the course, i.e. is each module a coherent block and the lessons within that module are appropriate to it?
  • Suggestions for activities and assessments during the course
  • Suggestions for a better title for the course – ideally the title should be short and snappy yet accurately describe the purpose of the course and its content
  • anything else that I haven’t thought of

Thanks. I'm looking forward to your comments and feedback.

mburridge avatar Sep 06 '22 09:09 mburridge

Excellent work @mburridge. I started looking at the course to check how it all fits together and it's an impressive work. I like how you divided it into sections and how you introduce new concepts as the work in the block progresses.

I have some technical feedback to share for the first two modules:

General note, code examples don't follow WordPress Coding Standards. I'm not sure if that is something that is important here or not, but it's noticeable for someone who is forced to follow them on the daily basis.

What is a block?

The block editor, also known as Gutenberg, is the modern replacement for TinyMCE which is the editor that WordPress traditionally came with and with which you may already be familiar. Although it is an ongoing project still under active development, the block editor is already mature enough to be the default editor in new WordPress installations.

Technically speaking the block editor is the default WordPress editor from WordPress 5.0 (December 2018). Initially, the editor used TinyMCE internally and it was refactored later in the development process. I wouldn't highlight it being strictly a replacement for TinyMCE. It's far more important to emphasize instead the concept of blocks and how it lets users edit every aspect of the WordPress site using a single interface. It isn't posts and pages anymore.

Scaffold your first block

npx @wordpress/create-block multi-columns

Side note here. If you don't provide a name of the plugin/block then Create Block will prompt questions on the terminal and the user is able to customize many things. In effect, instead of manually editing block.json on "Build and run your project" page, they could pick those values when scaffolding the project. It's fine to show how to edit block.json the way it is, but it would be also nice to let folks the tool is more powerful.

Understand the structure of the project

save.js exports a function that determines the markup that will be saved to the post_content field in the wp_posts table when the post or page is saved.

It isn't only a post or page, it's all post types, including templates used by a block theme.

Add ‘Block Supports’ controls

I have mixed feelings when seeing experimental APIs like "__experimentalDefaultControls" in the official educational materials. In general, this is something that is meant to be used only in the Gutenberg plugin. See the recent post on that topic: https://make.wordpress.org/core/2022/08/10/proposal-stop-merging-experimental-apis-from-gutenberg-to-wordpress-core/.

It would be great to figure out how to make this API stable in the upcoming WordPress 6.1 release so everyone could freely use the stable version without this experimental prefix.

Define default settings in block.json

There are a number of components that are marked with __experimental... in Gutenberg,

While this is a great hint, it might feel very confusing for someone who is exposed for the first time to learning about building blocks for WordPress. In the ideal world, we would present how to use only stable APIs so people don't need to learn about all those nuances.

gziolo avatar Sep 06 '22 10:09 gziolo

Module 3, 4 & 5

Create custom inspector panel controls

It's a bit painful experience to avoid using useBlockProps and pass styles through style for features that are handled by the block editor. It's fine though as a learning exercise as it gets refactored later. What I'm worried about, it can lead also to subtle bugs if there is any style generated by useBlockProps because the style prop will always override it. I would feel more comfortable seeing this code always passing custom style and className through useBlockProps.

Add more configuration options

I have a similar concern as in the earlier module about using the experimental API that isn't considered ready for production use: __experimentalNumberControl component. Can we avoid using it or find a way to make it stable in WordPress 6.1 first?

Work with the InnerBlocks component

This is my favorite part when inner blocks get introduced :heart: 🎉

Refining the project

That's really nice to present all the opportunities to simplify the code 💯

Add style variations

I like the idea of showing how to use style variations. There is a drop cap native support in the block editor. It works with Paragraph blocks out of the box. You can look for dropCap in https://github.com/WordPress/gutenberg/blob/trunk/docs/how-to-guides/themes/theme-json.md. The limitation though is that you can't control the drop cap for inner blocks from the parent block.

The finished project

I don't see any experimental APIs included on this page. This is great, I'm wondering why there is a disconnect with the previous modules.

gziolo avatar Sep 06 '22 12:09 gziolo

Thanks so much for reviewing the course @gziolo and for your comments and feedback. Thanks also for your very kind remarks.

General note, code examples don't follow WordPress Coding Standards.

The repo for the project is here. Please feel free to submit PRs that bring the code into line with the WordPress Coding Standards (if you have the time) where you discern that it deviates from them and I'll update the tutorial accordingly.

I wouldn't highlight it being strictly a replacement for TinyMCE. It's far more important to emphasize instead the concept of blocks and how it lets users edit every aspect of the WordPress site using a single interface.

Good point. The earlier parts of the course are the ones most in need of revision I think, so I'll factor that in when I come to review and revise the course.

but it would be also nice to let folks the tool is more powerful.

Ideally I'd like to keep the course tightly focused around the project being built and not have too many side avenues to distract the learner. @jonathanbossenger has created a separate tutorial on Create Block which I reference in that lesson. Do you feel that it's important to explain the scope of the tool at that stage of the tutorial?

It isn't only a post or page, it's all post types, including templates used by a block theme

Another good point, I'll take it into account when reviewing and revising.

I have mixed feelings when seeing experimental APIs like "__experimentalDefaultControls"

I agree and have similar misgivings, and as you say this is confusing for the user. I've rewritten the following two lessons to remove all reference to "__experimentalDefaultControls":

Thanks once again for your review.

I see you've just posted another comment above 😄 - I'll address that separately.

mburridge avatar Sep 06 '22 13:09 mburridge

General note, code examples don't follow WordPress Coding Standards.

The repo for the project is here. Please feel free to submit PRs that bring the code into line with the WordPress Coding Standards (if you have the time) where you discern that it deviates from them and I'll update the tutorial accordingly.

In theory, you should be able to run the following commands with npm run in the repository:

https://github.com/mburridge/multi-columns/blob/d3833f2eee965f51026b957128aa456408f72c57/package.json#L10-L12

npm run format
npm run lint:css
npm run lint:js

It probably gets the default version of Prettier installed instead of the forked one for WordPress. I guess it's the issue with npm aliases... Yes, I checked package-lock.json file and it resolves to the official Prettier:

"prettier": {
      "version": "2.6.2",
      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
      "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
      "dev": true,
      "peer": true
    },

I guess it's what most people will experience so we have to live with this for now.

but it would be also nice to let folks the tool is more powerful.

Ideally I'd like to keep the course tightly focused around the project being built and not have too many side avenues to distract the learner. @jonathanbossenger has created a separate tutorial on Create Block which I reference in that lesson. Do you feel that it's important to explain the scope of the tool at that stage of the tutorial?

Fair enough 👍🏻

gziolo avatar Sep 06 '22 13:09 gziolo

Moving this to "Review in Progress" column.

azhiya avatar Sep 06 '22 18:09 azhiya

It's a bit painful experience to avoid using useBlockProps and pass styles through style for features that are handled by the block editor. It's fine though as a learning exercise as it gets refactored later. What I'm worried about, it can lead also to subtle bugs if there is any style generated by useBlockProps because the style prop will always override it. I would feel more comfortable seeing this code always passing custom style and className through useBlockProps.

I take your point, but as you observe this is a learning exercise. The presumed audience is developers new to React and maybe even new to JavaScript, having come from a PHP background. I'm trying in the course to introduce concepts gradually and in this instance show them a way to do it that they might already be familiar with, or at least able to understand the code, and then refactor it to show them a more "React way" of doing the same thing which might initially seem conceptually alien.

I don't know, I think this is a better way but I'm open to persuasion that your suggestion of introducing useBlockProps earlier in the course might be better for the learner.

There is a drop cap native support in the block editor. It works with Paragraph blocks out of the box.

Is that theme dependent? When using Twenty Twenty-Two the drop cap doesn't seem to be available. In any case it's a learning exercise and demonstrates how to use is-style-{slug} in the scss file. I couldn't think of another example for a style variation but am open to any ideas you might be able to offer in place of the Drop Cap style variation.

I don't see any experimental APIs included on this page. This is great, I'm wondering why there is a disconnect with the previous modules.

That's coz there aren't any! 😄 The example you mentioned in your earlier comment was a transitory thing which was replaced with a better version in the course. That has been removed now because, as you said, it was confusing for the learner and I now realise it was actually a bit redundant.

The other instance where an experimental component is mentioned is a box out in this lesson where it's referenced in case the learner has come across it elsewhere and they're discouraged from using it. Do you think it's better not to mention it at all?

Thanks for your kind comments on the other items, and thanks again for taking the time to review the course.

mburridge avatar Sep 07 '22 11:09 mburridge

It's a bit painful experience to avoid using useBlockProps and pass styles through style for features that are handled by the block editor. It's fine though as a learning exercise as it gets refactored later. What I'm worried about, it can lead also to subtle bugs if there is any style generated by useBlockProps because the style prop will always override it. I would feel more comfortable seeing this code always passing custom style and className through useBlockProps.

I take your point, but as you observe this is a learning exercise. The presumed audience is developers new to React and maybe even new to JavaScript, having come from a PHP background. I'm trying in the course to introduce concepts gradually and in this instance show them a way to do it that they might already be familiar with, or at least able to understand the code, and then refactor it to show them a more "React way" of doing the same thing which might initially seem conceptually alien.

I don't know, I think this is a better way but I'm open to persuasion that your suggestion of introducing useBlockProps earlier in the course might be better for the learner.

I had to check how useBlockProps is documented to have a better overview of why we have a different understanding how this should be explained. This is the code documentation:

https://github.com/WordPress/gutenberg/blob/35f14cc073e97a4c14c01bb5c28ac40944282964/packages/block-editor/src/components/block-list/use-block-props/index.js#L45-L52

This hook is used to lightly mark an element as a block element. The element should be the outermost element of a block. Call this hook and pass the returned props to the element to mark as a block. If you define a ref for the element, it is important to pass the ref to this hook, which the hook in turn will pass to the component through the props it returns. Optionally, you can also pass any other props through this hook, and they will be merged and returned.

This is a way to mark a HTML element as a block wrapper in the editor. It means that this is where all additional HTML attributes get injected to ensure that the block integrates seamlessly with all the UI elements like block toolbar, inspector controls, and related interactions.

The most important code looks as follows:

https://github.com/WordPress/gutenberg/blob/35f14cc073e97a4c14c01bb5c28ac40944282964/packages/block-editor/src/components/block-list/use-block-props/index.js#L145-L171

return {
		tabIndex: 0,
		...wrapperProps,
		...props,
		ref: mergedRefs,
		id: `block-${ clientId }${ htmlSuffix }`,
		role: 'document',
		'aria-label': blockLabel,
		'data-block': clientId,
		'data-type': name,
		'data-title': blockTitle,
		className: classnames(
			// The wp-block className is important for editor styles.
			classnames( 'block-editor-block-list__block', {
				'wp-block': ! isAligned,
				'has-block-overlay': hasOverlay,
			} ),
			className,
			props.className,
			wrapperProps.className,
			useBlockClassNames( clientId ),
			useBlockDefaultClassName( clientId ),
			useBlockCustomClassName( clientId ),
			useBlockMovingModeClassNames( clientId )
		),
		style: { ...wrapperProps.style, ...props.style },
	};

There is a ton happening here, but what's most important is that you better pass all props through this function (yes, it's also React hook) to ensure that the block editor is able to merge everything together.

Now, let me explain a few issues with the code example included like:

    return (
        <>
            <RichText
                {...useBlockProps()}
                tagName="p"
                onChange={onChangeContent}
                value={attributes.content}
                placeholder={__("Enter some text here...")}
                style={{
                    columnCount: attributes.columnCount,
                    color: attributes.style.color.text,
                    background: attributes.style.color.background,
                }}
            />
        </>
    );

useBlockProps returns a long list of props that you can read from the code above including style. The code above also defines style. The way React works is that the last occurrence of the same prop wins, so any style provided from the block editor gets ignored. If you would also pass classname in the addition to that, then it would replace the long list of class names that the block editor needs to work correctly.

The other challenge is that useBlockProps is a React Hook so it needs always run and be in the same order. In effect, it's better to put it before the return statement. In effect, the way to minimize potential mistakes the following would work best in my opinion:

    const blockProps = useBlockProps({
        style={{
            columnCount: attributes.columnCount,
            color: attributes.style.color.text,
            background: attributes.style.color.background,
        }}      
    });
    return (
        <RichText
                {...blockProps}
                tagName="p"
                onChange={onChangeContent}
                value={attributes.content}
                placeholder={__("Enter some text here...")}
            />
    );

The developer experience is suboptimal here because it's hard to explain that className, style and ref have special handling here. It's a tricky one and super confusing, and the same pattern for passing props should apply to useBlockProps.save that is a regular function in save.

Aside: the following code would also work:

    const blockProps = useBlockProps({
        style={{
            columnCount: attributes.columnCount,
            color: attributes.style.color.text,
            background: attributes.style.color.background,
        }}
        tagName="p"
        onChange={onChangeContent}
        value={attributes.content}
        placeholder={__("Enter some text here...")}
    });
    return (
        <RichText {...blockProps} />
    );

I don't think it's used this way for core blocks. It's all about the mental mode where we mix block wrapper props with the props specific to the React element that we enhance. I wish we had a better story for it.

The interesting aspect here is that if we were to pass an id to the RichText component this way and with the previous way, then it would produce a different result. Here the block editor would override the id passed with the one from useBlockProps, but in the previous examples, it would use the id passed directly to RichText and that might have an unpredictable impact on how UI works.


There is a drop cap native support in the block editor. It works with Paragraph blocks out of the box.

Is that theme dependent? When using Twenty Twenty-Two the drop cap doesn't seem to be available. In any case it's a learning exercise and demonstrates how to use is-style-{slug} in the scss file. I couldn't think of another example for a style variation but am open to any ideas you might be able to offer in place of the Drop Cap style variation.

Yes, theme authors can disable certain features, including all other shared controls that are featured in the course. The same thing can happen to colors or padding when they get disabled. The other story is that block style variations need better integration with the features that themes can control with theme.json.


The other instance where an experimental component is mentioned is a box out in this lesson where it's referenced in case the learner has come across it elsewhere and they're discouraged from using it. Do you think it's better not to mention it at all?

I see what you did. You were faster than I was able to process the course 😄 I would keep an eye on that and double-check with folks new to the block development. As I mentioned before, it would be great to show only stable APIs in all educational material and hide experiments for internal usage in the Gutenberg plugin. I also can see how the code copied for the custom React component can work as a way to teach that you can build your controls, too.

gziolo avatar Sep 09 '22 08:09 gziolo

@mburridge I'm finally able to focus on reviewing the course. I will leave notes here on a per-module basis, in separate comments.

Introduction and Module 1

General comments: Great introduction and first module! I like how you keep it light, engaging, and focused on the learning outcomes. I'm excited to move through the rest of the course.

Specific comments

Introduction

  • Just a reminder to remove the Objectives Document.

Module 1

What is a block?

  • <fact check this!!!> note left it content

Understand the structure of the project

  • I'm wondering if the dark mode screenshot is less readable than a light mode one? Just my opinion.
  • It may be useful to include the register_block_type() code after the paragraph where you explain it, for context.

jonathanbossenger avatar Sep 12 '22 12:09 jonathanbossenger

Module 2

Make the block interactive

  1. On the section adding the destructured attributes to the Edit component's function

export default function Edit({attributes}) {

It's not clear that the block props are always passed to the Edit (and save) function, and that they contain the attributes object from the block.json (among other things). So a sentence or two explaining this might be helpful. I do this in my Attributes tutorial (which you can see here at about 2:25 on the video)

  1. In the section where you're adding the onChangeContent function
const onChangeContent = (val) => {
        setAttributes({ content: val });
    };

It's not clear where this should be in the Edit function, so it might be ideal to clarify that it needs to be before the return but inside the Edit function.

Add ‘Block Supports’ controls

  1. As far as I know, the Inspector Panel is referred to in the Block developer handbook as the Settings Sidebar while the component used to render items in that sidebar is called InspectorControls, so it might be a good idea to use the same name used in the docs.
  2. When adding color supports. and changing for example the background color, the .has-background class is applied to the p tag, which includes a default padding. It might be useful to mention that this is expected and that we'll customize that in the next step when adding spacing supports.

Define default settings in block.json

  1. Reminder to remove or update the Activity

jonathanbossenger avatar Sep 12 '22 12:09 jonathanbossenger

Michael, let me just take this opportunity to congratulate you again on doing a superb job. It is no easy feat to create a course like this!!

Here is some feedback from my side:

Solid introduction!

Module 1 What is a block? There is still this note about 'fact check' image

Understand the structure of your project Spend instead of spent image

Build and run your project It might read better if we add a comma after Next? I have seen this in a few other places as well. image

Change 'the' to 'then' image

I would suggest breaking this sentence up into two parts image

Create custom inspector panel controls Add a comma after However. There are a few other instances as well. Just a suggestion. image

Heading and paragraph should be capital letters = Heading block / Paragraph block image

Add more configuration options Chosen instead of chose image

I would suggest breaking this sentence up into two parts: image

Configuration options for the separator though should be through image

I suggest breaking up this sentence into two parts image

Add Style Variations Should it be previews or preview (singular)? image

Conditionally display controls I assume truthiness is a commonly used word amongst coders? I had to google it :-) image

Wrapping up Remember to remove these lessons ;-) image

Quizzes: I assume these must still be created? image

westnz avatar Sep 16 '22 04:09 westnz

Module 3

Create custom inspector panel controls

  1. Same note as earlier regarding Inspector Panel vs Settings Sidebar
  2. In the last lesson, the activity you asked the learner was to update the block to be wrapped in a div and not a p tag. Then when this lesson continues, the RichText component is still using a tagName of "p", so it might be a good idea to either tell the user to switch back to "p".
  3. Additionally, the last time you referred to the edit.js file, it just contained the RichText component. Then here, the RichText component is wrapped in <></>. I understand why this is, but the new learner might not. I also think this is a very important piece of React information, the fact that a React component can only have one top-level element. Also, it's probably only important to include this when the RangeControl component is used.
  4. This is the first time in this course that the code in the style.scss file is shown, so it might be confusing to the learner. It would either be useful to show what's in the style.scss file when you first reference it in module 1, or simply show what's currently in that file from create-block, before adding the column-count value.
  5. The course should probably guide the user on how much lorem ipsum text to add. For example, only using a sentence and setting column count to 4 only appears to render two of the columns. So it should probably specify something like "at least 2-4 sentences of text"
  6. I think what is needed in the section about background colors, is to explain the fact that because the RichText component is using useBlockProps, it's applying the styling from the style.scss file, but because the style object was defined in the block.json, this overrides anything set in the style.scss file. This explanation would also help with understanding why the styles from the file in item 2 above aren't already being rendered. This explanation will be helpful to developers, as there might be cases where they want to leave the styles in a stylesheet vs where they need to control that style element via block attributes, so this explanation is a great opportunity to explore the differences.
  7. I think that the section where you explain your reasoning behind the logical limits for the columnCount would be more impactful as a numbered list, instead of a series of paragraphs. A numbered list "breaks" the flow, and alerts the reader that something different/interesting is being presented.
  8. The last time the learner saw the imports from @wordpress/block-editor, they were all on one line, now you have them on new lines. Might be worth just mentioning both options work.

Add more configuration options

  1. In the section where the NumberControl is being created/imported, it might be useful to give a short (one or two sentence) explanation. While I agree that it's outside of the scope of this course, knowing what Number control is, and why you import it differently to WordPress components is useful to know.
  2. If at any point in time the user has chosen to save the post or page they have added the multi column block to, and they edit the edit.js and save.js code (to add the columnWidth or columnGap values), the block editor will display the "Attempt Block Recovery" UI (as the saved code and the save function will have changed). It might be useful to mention this in a callout.

jonathanbossenger avatar Sep 16 '22 07:09 jonathanbossenger

@mburridge Let me reiterate Wes' earlier comments, congratulations on doing a great job putting this course together. As I'm sure you know, creating a full course is no easy task, and I think you've done a wonderful job. I learned a bunch about block development.

Sadly, I was not able to complete a full review of the course in time, and I only managed to review up to module #3. However, I did not find any specific technical bugs, so I'm sure the rest of the course is technically correct.

As mentioned in an earlier comment, I've reviewed and left notes on a per module basis. Mostly what I've focused on where a) technical accuracy (did the code presented work for me) and b) new user flow (was I able to understand what was presented, step by step). I also tend to be very verbose in my feedback, so what you will probably see as walls of text could probably be trimmed down to one or two sentences.

I will add that nothing I have suggested is super critical, so you are welcome to ignore anything that I have added, I'm merely sharing what I would do differently if it was my course.

Again, congrats on the course content, I'm super excited to see it published! 🎉

jonathanbossenger avatar Sep 16 '22 07:09 jonathanbossenger

Sadly, I was not able to complete a full review of the course in time, and I only managed to review up to module https://github.com/WordPress/Learn/issues/3.

@jonathanbossenger thanks so much for reviewing up to this point and for your detailed feedback. Please feel free to continue reviewing as the time limit was imposed in order to provide some sort of deadline for community reviews. TBH I'm still open to receiving feedback from all sources, and I especially want the later stages of the course reviewed as the content gets increasingly more technical.

mburridge avatar Sep 16 '22 08:09 mburridge

@westnz thanks for your feedback. I'll make sure to address the points you raise.

mburridge avatar Sep 16 '22 08:09 mburridge

TBH I'm still open to receiving feedback from all sources, and I especially want the later stages of the course reviewed as the content gets increasingly more technical.

@mburridge ok thanks. I will keep it on my radar and do my best to review the rest of the content in the coming weeks.

@westnz as a side note, we might want to consider that reviewing a course takes considerably longer than reviewing a tutorial or lesson plan, and so we might need to allow more time for a course review.

We could still always publish the course, and ask any training faculty SMEs to review as/when they have time.

jonathanbossenger avatar Sep 16 '22 09:09 jonathanbossenger

Agreed, I'm not averse to extending the review period. In fact I expect the course to undergo changes and revisions even after publication as feedback comes in from people actually using the course to learn from describing where they're getting stuck or where explanations are inadequate or unclear.

mburridge avatar Sep 16 '22 11:09 mburridge

Good idea @jonathanbossenger We could still always publish the course, and ask any training faculty SMEs to review as/when they have time.

westnz avatar Sep 19 '22 01:09 westnz

I'm going to have to rewrite part of the course. There's a bug in the code that I didn't pick up earlier, it's a "subtle bug" that @gziolo referred to above. He also goes into some detail as to why useBlockProps should be introduced earlier in this comment.

Although "subtle" the bug is pretty fatal for the course. To get around it I would either need to introduce code that later gets removed, which is messy and potentially confusing for the learner, or I need to introduce the useBlockProps hook earlier in the course, as Greg suggested.

I’m going to go down the latter route, but it’s going to entail some rewriting and restructuring of the course.

Note: To see the problem for yourself complete the project in the course up to the end of the lesson "Create custom inspector panel controls" in Module 3, then try changing both the text and background colour of the block.

mburridge avatar Oct 06 '22 12:10 mburridge

The good news is that I’ve finished re-structuring and re-writing sections of the course so it now not only circumvents the bug but is also now in accord with Greg’s suggestion. TBH I think it’s made the course better than it was.

This week I will be adding some activities/assignments/quizzes to the course with a view to getting a first version of the course published by the end of this week or early next week.

What would be great is if we can get a couple of people to run through the course and build the project from start to finish in order to test each step in sequence to check that each of the coding steps work as expected.

mburridge avatar Oct 11 '22 11:10 mburridge