Okay, we are live, we arerecording. Welcome to everybody
joining us today. Apologies forbeing a few seconds late, I was
having some zoom issues, I thinkI may have either incorrectly
copy the meeting URL or not setsomething up properly. Because
when I open up zoom today, Ididn't have a scheduled meeting
to trigger. So Alvaro iscurrently with me today was was
pinging me on slack to say, Hey,we are you and I was going I
don't know, I don't know what todo. So welcome, everybody. While
you are joining, if you aregoing to code along with us
today, please do get your localenvironment ready. You will need
a local WordPress installationusing something like local WP or
dev Kinsta or WP E and V or MAMPor Wempe or any of those. You
will also need a code editorlike VS code or Sublime if you
want to code along with metoday. And then the pipeline
block code which we worked onlast week. If you haven't got
it, we will download it duringthe course of the zoom session.
So you've got some time to getthat set up. And then just pop
us a message in the chat and letus know where you're joining us
from. And maybe what part of theworld you're joining from. I am
going to turn around and poursome water into my coffee
because I made my coffee a bitlate today. So give me a minute.
And Alvaro, why don't youintroduce yourself while I'm
doing that?
Yeah, my name is Alberto. I'mstaying. I'm a happenings
engineer in wordpress.com. Whereare you all from?
I've been I've I've beenpronouncing your name wrong.
I've I've been saying it overand over.
Yeah, like it's got an accentmark on the air. But I rarely
use it because it messes up thealphabetical order. Because
yeah, so we've got folks fromDACA. We've got folks from
Munich. Everybody's signing inand says Good. Cool. So yeah,
but those of you who don't knowhi from India, those of you have
never seen me before. My name isJonathan. I am from Cape Town in
South Africa. So I'm way deepinto the southern hemisphere and
scientific, lovely and warm herenow. I'm an ex developers code
instructor. I'm currentlysponsored contributor to the
training team at Automattic. IAdrian from Anaheim. And you can
find me for as long as it'saround on Twitter. At John
underscore Bassinger. It's beenan interesting interesting few
weeks watching, watching Twittersort of implode. Okay, so today
we are going to be following onfrom a session that I started
last week we're going to bebuilding some WordPress blocks
without using React. And when Isay React without using React,
what I mean is we're not goingto be using JSX, which is the
React sort of syntax for forbuilding elements. We're not
going to be using the buildtools, we're just going to be
coding vanilla JavaScript. Lastweek, we built a very simple
block, which I'm going to justopen up the link to here
quickly. Grab that out and popthat in the chat quickly. My
screen just did something weirdand if it affected you all. But
if you want to grab that plug inyou can do and then I'm just
going to save this onto mydesktop now. And I'm going to
open up my WordPress instal No,that's the wrong one. The
problem with calling your namingyour things after products that
exist. I think I already have itinstalled. No, I don't. So let
me just add now quickly, if youwant to code along, you're
welcome to instal it as well. Ifyou were here last week, and you
were you were working throughtheir code, and you still have
their code from last week, youcan use that as well. But
basically, what we built andI'll go through it all in a
second was just a very simpleblock that renders some content
to the editor, render somecontent to the front end. And
we're going to basically bebuilding on top of that blog
today. Before we get started,let me get some announcements
out of the way let me justchange this. Welcome, everybody.
And thank you also to Oberoi forher co hosting today. Velma was
supposed to be joining us today,but she's not feeling well. So
I'll row stepped in at the lastminute. So I appreciate that. We
are presenting in focus mode asalways, but if you would like to
please do consider enabling yourvideo. If you would like to
React to my my workshop, you'remore than welcome to you don't
have to it's not a requirement.You're welcome to ask questions
as we go through the session.You're welcome to either post
those questions in the chat orunmute and ask those questions.
The only the only thing that Ido ask is if the question
doesn't specifically relate towhat we're doing on screen at
the time, then please hold it. Ido have pauses where folks can
ask questions that are sort oftangentially related to what
we're doing. So please try andhold those or just ask them in
the chat and although we'll seethem and if he feels like we
need to stop and cover them up.You know, okay, then I'm
supposed to be talking about theend of my workshop, but I often
run out of time. So I'd like tocover it first. But if you are
following the tutorials and theworkshops and the things on
learn on the Learn WordPresswebsite, and you want to share
your voice about what you wantto get from the platform, what
works, what doesn't work, pleaseconsider taking the Learn
WordPress loader survey. It'sbasically our sort of process of
gathering feedback from thecommunity about what we folks
think we're doing well, whatwhat we need, what new topics we
need. And we'd like to get asmuch feedback from that as we
can, while we're busy, plan outour goals for the training team
for 2023. So please do considertaking that after this workshop
or with us whenever you havetime. final reminder, if you are
coding along to download thatzip pass along, or you can do it
in a second, but it will behandy to have that. And then the
last few things if I'm going toofast, please stop me, let me
know. I will be posting thesession to WordPress.tv
afterwards sometime during thecourse of the day tomorrow. So
if you want to catch up later,you can do it that way. And then
for more WordPress focusedcontent, please visit learn
wordpress.org. There have beensome awesome blog development
courses added there recently,some block themed development
courses. So there's lots of newcontent coming up all the time.
So please do check that out.Okay, our learning outcomes for
today. So today, we are going tofirst of all have a look at last
week's code and just remindourselves what we did. Then I
want to dive into some sort ofgeneral Developer Tools
principles for BlockDevelopment. And it's just some
of the things that you can usein the browser and some of the
processes that you can follow tokind of make your life a little
bit easier. Then we're going toadd an attribute to the block we
bought last week, and theattribute we want to add so that
we can enable users to edit thatblock, we're going to make it
possible to edit and save theblock attributes, we're going to
be doing a very simple way ofdoing it. And then we're going
to implement a slightly moreadvanced way, which is to use
the rich text component to givea better user experience. So
those are the five things wewant to try and cover today. Our
actual fine detailed objectivesis that I want to kind of review
browser dev tools, and also howto clear the browser cache
because those are things that Iuse a lot when I'm developing
blocks. Because everything isJavaScript based. We're going to
change when we have a look atthe code, this will make a bit
more sense. But one of the firstthings we're going to do is
going to change the element thatthe DOM element for the edit
function from a paragraph to atext area, so we can make it use
editable, we're going to add thestring attribute to the block.
And then we're going to spend abit of time talking about the
difference between the blockprops and block props. Now they
sound the same, but they're kindof not. So we're going to talk
about that make sure weunderstand what those two things
do. And then we're going to usethe attributes content in the
edit function. So we're goingto, I'm going to show you ways
that you can access theattributes in multiple different
ways. And then you can decidewhich which process in which
path you want to take. Thenwe're going to update the save
function to use that access userattributes so that when it saves
the block, it saves theattribute data and is rendered
on the front end. And then we'regoing to add the unchanged
functionality so that when auser makes a change, it actually
saves it in the right places.And then finally, we'll
implement the rich textcomponent just to make it look
better. And you'll see what Imean when I say make it look
better when we get into it.Because when we use the text
area, it doesn't look great.It's not a great user
experience. It doesn't give alot of functionality. But using
the rich text component does,and it's a way that you can use
WordPress packages WordPresscomponents inside of your blog
code. Okay, I'm going to poursome water into my coffee and
pour my coffee in my cup. Ifanybody has any questions, or if
anybody needs to get set up or,or get their local environment
set up, now's a great time to doit. Well, that wasn't us.
Usually, I have my coffee readyto go before these workshops
because of the Zoom issues I hadearlier. I didn't do that. So
you have to be with me and Imove some things around on my
desk. Yeah.
Question. So can we get Reactrecording?
Yeah, go ahead. Yes. So yeah, sothe recording link, I won't be
able to do at the end of thismeeting, but I will do it
tomorrow. So during the courseof my Friday, because when I do
these workshops, they're rightat the end of my day, so I
basically finish the workshop,close my laptop and I go home.
And then first thing tomorrowmorning, what I do is I download
the video from from the Zoomaccount, I upload it to
WordPress TV, and then I sharethe link to the Meetup group in
the comments. So you willdefinitely get the recording
sometime during the course ofthe day tomorrow. And you'll be
able to then watch it wheneveryou want to. So thank you for
that question. There. Okay.Let's get to some coding. So the
first thing I want to do is Iwant to just review the block
code that we worked on lastweek. If you've downloaded the
zip file you should have this inyour local WordPress instal as
well. My Visual Studio is nowcoming absolutely open us up
over here. In the pluginsdirectory, it's the WP hyphen
learn hive and JavaScript fileif you've installed it and
activated it. And in that file,we created a few files. Last
week, we created the block dotjson file, which contains
various information and metadataabout the block. It has a title,
it has the name of the block.Last week, I think when we were
doing this, we called it basicblock. I've updated that to make
a JavaScript block today, justso that it's easier to work
with. So if you're using thecode from last week, please
consider updating yours to matchmine to WP hyphen, learn
JavaScript slash JavaScriptblock, we set the category we
set the icon and we set it it'sa script file, which is
basically the block code. Wealso set some styling. So we set
the editor style and the mainstyle. Then we worked on the
block code itself. And this iswhat the block code looks like.
And we basically I just usingthe blocks element and Block
Editor packages from theWordPress global objects, and
passing them into our function.And if you remember that
function is a autumnautomatically running function
or iffp. I can't remember thedetails of it. I just want to
actually, while I think aboutthis, I want to I don't think I
had a tear in my resources. No,I didn't. I want to share the
recording of this workshop fromlast week. So that those of you
who want to watch it, see whatwe did last week can can do
that. So it's going to be aroundhere somewhere. No, it's not.
Let's do this. No, I'm not goingto find it now am I developing
without ever go developingwithout React. That's part one.
So if you want to see how webuilt what we're working on
today, this is part one, this iswhat we did last week, you're
welcome to watch that. And thenand then try this out later. But
for now, we're just going tocontinue on. So we use this
Create Element function, and webasically pass it to a variable.
And then we'll use that tocreate the element in the Edit
and Save functions of the block.Here we are registering the
block type giving it the samename, as we specified in the
block JSON. And then we haveedit function, which has all the
functionality that happens inthe editor. And then the save
function, which is the functionsthat happens when the block gets
saved to the database. And allwe did was we had some some
text. So hello, JavaScript worldHello JavaScript world. We
implemented the block props,which is a special React hook,
which we're actually going totalk a little bit about more
today. So we understand whatthat does and how it works. And
you'll see on the front end,we'll talk about what that did.
And then the other thing we didwas we created this block asset
file, which basically sets upall the dependencies. So it was
the blocks dependency, theelement dependency, the Block
Editor, dependency, and thatpolyfill, which enables all of
this non React stuff for us. Andthose are the three main files
that we needed in terms ofcreating the block itself. And
then lastly, the fourth file wasjust initialising, the block in
PHP. So using the register blocktype PHP function, passing it
the current directory, so it canfind the block that JSON file to
start registering things. Andtaking it through from there. So
that's everything that we didlast week. shabam says changing
the block name also change theclass name that was created
automatically. Yes, good point,I'm getting to the styling now.
So very good point there. Thenthe styling we did. So in the
block JSON, we said there was aneditor style, which was the
editor dot css file, and thestyle file, which was the style
dot CSS file. So in the editordot css, we had the class name
that was automaticallygenerated, which was WP block
learned JavaScript JavaScriptblock. So if yours is basic
block, and you want to followalong, please change that to
JavaScript block today. And wejust created a green background
white colour for the text and 20pixels of padding. And then for
the green very fast, and this, Ido apologise, we'll stop in a
second. And then in the in thefront end styling again, learn
JavaScript JavaScript block. Andwe gave it a red background,
white colour and white and, and20 pixels of padding or 50
pixels I think we did last week,I'm leaving it at 20. Now. So
it's a very basic block. Verysimple, very straightforward. If
we have a look at that inWordPress, we activate this. And
we go into a post and we addthat block. And this is why we
named a JavaScript block so itcomes up easier when I search
for it. That's all it does. Aneditor is just some text, we can
move it around at least and thatwas where you know, block props
came in handy the ability tomove it up and down the ability
to remove it from here. And thenif we preview this, in the front
end, it has the red colour.There it is in the front end. So
that's all we did last week.Very simple, very
straightforward. That's thebasis and we're going to start
from today. Does anybody haveany questions around everything
that I've just gone throughvery, very quickly. If you
weren't here last week, if youhaven't ever built a blog from
scratch before some of Thismight be new. Unfortunately, I'm
gonna be able to cover it again.But you can watch that recording
that I that I shared earlier.But does anybody have any
questions around all of thatbefore we get started?
If you don't seem to havequestions, so I think we can get
going. Here we go. This is agood loss it toolbars are not
having the upper block that yourscreen shows. But as soon as I
add, everything was workingfine. Oh, yes, I remember you
had that problem last week.Excellent. I'm glad you got that
work worked out. Excellentstuff. Okay. So they don't seem
to be any questions. So I thinkwe can move forward. So just as
a reminder, the thedocumentation that we're working
through is in the Block Editorhandbook. So if you go to
develop a.wordpress.org in abrowser, and you're welcome to
open this up, because we'regoing to be using some of this
code today. On the DeveloperResources page, third item from
the top says Block Editor, or atleast in my English version, it
does, if you're using adifferent language, locale, it
might say something different,but it's usually the same icon.
And then you've got this linksfor building of blocks. And that
takes you through to the BlockEditor handbook. And then there
are these How to Guides. So I'mgoing to open that quickly. And
the first one is accessibility.And the second one is blocks.
Now, one of the reasons that I'mdoing this series of workshops
is because the way that theBlock Editor handbook is kind of
put together, as you can see asalphabetical accessibility
first, then blocks indevelopment platform. And then C
comes and it's kind of, it'skind of very difficult when
you're first building blocks toknow where to start. And so what
I did when I first startedbuilding blocks was I hit this
how to guide and I hit thisblocks, how to guide, and it was
a tutorial to take me through.But then there's got some links
of moving around, and bold stepsand all kinds of other things.
And I found it very difficult tofollow. So the goal of today, or
at least the goal of this seriesis we're going to work through
each one of these pages, andunderstand what's going on on
the pitch. Last week, we did, wedid the create a basic block
step. So it was setting up theblock json file, setting up the
block registration, setting upthe Edit and Save functions,
adding the dependencies, andthen making sure it all works.
And then the next thing we didwas we the next tutorial was the
using styles and styles. So wedidn't go the inline style
route. We discussed it verybriefly. But we went the block
class name route, which is whatshabam was mentioning earlier,
we implemented use block props,and we use the class name that
that generates. And then weinclude the style sheets, the
editor dot css and the style dotCSS. And that's and that's where
we ended up. The next one isattributes, editable fields,
which is where we're going tostart today. So if you if you
have that open up in yourbrowser, please do to navigate
to that page now. And the veryfirst section is is about
attributes. So it says the untilnow the Edit and Save functions
have returned a simplerepresentation of a paragraph
element, which is what we sawearlier. We've also learned how
these functions are responsiblefor describing the structure of
the blocks appearance. If theuser changes the block, the
structure may need to change toachieve this, the state of the
block is maintained through theediting session as a JavaScript
object. And when that updateoccurs, the edit function is
invoked again. So what we needto do now is we need to now
figure out how can we maintainthe representation of that
object to be able to allow folksto edit it, and that's where we
can start using blockattributes. Okay. Now, if you
have a look at this code, and ifyou scroll down, or you can just
have a look on my screen here,we're going to scroll down to
the bottom where they show theattributes being registered.
You'll see that they'reregistering in this in this code
example, I'm going to switch tothe plain version. Why is
software trying to update whenI'm doing a zoom call no go
away. In this example, theattributes are being defined
inside the register block typefunction. And if you'll remember
from our first step, when wecreated the block JSON, we set
those things up in the blockJSON file. So when I was working
through this documentation thefirst time and I saw this, I
went, but hang on. Now my APIversion, my title, my icon, my
category is suddenly in myregister block type should I be
doing it this way? And theanswer is both ways work. You
can either register yourattributes as an object in the
register block type, or you cando it in the block that JSON
file. So one of one of my goalsis going through these workshops
is also to get thisdocumentation updated to follow
a specific process one or theother, with notes on the
alternatives. But here it's gotattributes being defined inside
register block type, but we candefine the same set of
attributes inside the block theJSON file. So all I'm going to
do is I'm going to copy out thisattribute section Yes, the
content type source and selectjust this part over here. And
then we're going to switch overto my blog dot json file and it
doesn't matter To add at whatpoint you insert attributes,
personally, I like to do itafter the name field in the blog
to JSON file, that's just apersonal choice, you could make
it first you could make asecond, it's a JSON object, it
doesn't matter. But I like to dooften now. So I'm going to pop
that in there. And you'll seeimmediately it starts throwing
me some errors, because in theblock dot json file, my my field
names need to be in quotes.Whereas when you specify them
inside the callback to thebrowser, when you specify them
inside the register block typefunction, you can just leave
them without quotes. So that'sthe one difference. So back over
here, I'm just going to see if Ican, this is not going to allow
me to do this, I'm going to doit manually. So I'm going to put
attributes in double quotes. Andthen I'm going to put content in
double quotes. And then I'mgoing to put type in double
quotes, and source and selector.And then it's also given me the
same issue here with strings, Ihave to do double quotes there
as well. And the same for thisone. And the same for this one.
Here we go. And then I'm gettingsome errors on the commas. And
that's because JSON objectsdon't like a comma at the end of
an object and the last item, soI'm going to remove that. And
I'm going to remove that. Andthat's what I ended up with.
Now. If you just typed all ofthat along with me, or if you're
looking at that on the screen,and you're going, okay, sure,
but what does that all mean?That's kind of what we're going
to dive in today. But for now,all I want you to do is
understand that we're setting anattribute with a name or a
title, if you will, of content.So we're going to, we're going
to be referring to content. Soit's the content of the blog. It
has a type of string, whichmeans it expects some form of
string, so not another object ornot necessarily something else.
It has a source of HTML, whichI'm going to explain to you in a
second, and has a selector of p,which is a paragraph tag as
those of you know, HTML. Now,what that means is, when I apply
this attribute to my blog, it'sgoing to look for a a DOM
element or an HTML element, ifyou will, with the selector of
p, in other words, a paragraphtag. And it's going to read the
HTML source of that paragraphtag. And that's where the source
HTML comes in, as the attributescontent, and when it updates the
content, it's going to updatethat back to the same place. So
that's what all of that means.Now, if you open up a think I've
got this in my in my resources,so we will grab that now
quickly. There we go blockattributes. And this is the
reference guide. In the BlockEditor, it's going to open up
that I just pop that in, in thechat. And it talks about block
attributes provide informationabout data stored by the block.
So this is your your blocksdata. So you can have multiple
attributes. You can have richcontent, you can have a list of
images, you can have background,colours, button titles, all
kinds of things can beattributes of a block. So we can
think about them as likevariables of a block can contain
a number of attributes. Andthese are specified by the
attributes field. An attributedefinition will contain at a
minimum, either a type or anenum. So what that means is we
can actually, if we go back tohere, we can actually take all
of this out, and just specifywithout the comma, just specify
the content attributes as a typeof string, and then it'll work.
And I'm going to leave that in.But we could do that if we
wanted. If we go back to thedocumentation here, it shows
some examples. So you might havea URL attributes, which is of
type string. And it's going toget the add that image selectors
so the image tag of the block,it's going to look for the src
attribute on that selector, andthen it's gonna get that value
and put it into that string andstore it and save it for the
block. Or you could just have atitle that is just a type
string. Or you could havesomething like a site. So
there's multiple differentattributes that you can set up
now there are only be 30 reallybecome sort of understandable,
once you start applying them tosome kind of element. So for
now, if it's confusing, don'tworry, because as soon as we
start applying it just not to atext area, you'll start
understanding what's going on.Okay. Any questions on setting
ups of attributes? Everyonesays? Yeah, yeah. So this is if
this is how you could add anARIA label, I actually think and
we're going to dive into this ina second, the ARIA label I
think, is actually set by theblock props. So so hold on to
that question, Adrian, becausewe're gonna get to that in a
second. So what I want to showyou now and I'm going to jump
back to my, my slides to remindmyself what the next step was,
because I forgotten as we wantedto look at the code, we wanted
to sit down, so I've jumpedahead a little bit
But we wanted to first reviewdeveloper tools and browser
cache, which I'll get to in asecond. And we wanted to change
the element filter function.I'll get to that in a second.
But let's go back to the code.And let's just see where those
attributes attributes come intoplay. So in your, if you're
coding along with me, open upyour block.js file, and inside
of your edit function, inside ofthat function, open, close
brackets, just put in the wordprops, okay? You didn't have to
make it props, you can make itproperties as well, if you want,
either one would work. But thesort of industry standard is to
call it props. And then what Iwant you to do is I want you to
console log props. So console,log is a developer tools, thing
that you can do. And it'lloutput the value of that
variable to your browser to yourbrowser developer console. But
what I also want to show yousomething very cool, which is,
and this is part of the showingyou how Dev Tools works, is you
can actually set up an object byusing the curly braces and then
give it just as you would anormal JSON object, give it a
name, or a title, or whatever.And I'm going to call this edit
props here. And then when itlogs to the console, I can
actually then see where the codeis, I've got multiple things
that I'm logging, I can givethem names, and I can find them
easy. So that's what we're goingto do for now. So in the block
that JSON, we're going to set upthe attributes, we're going to
set up the first attributecalled content, and we're going
to give it a type string, sourceHTML and select a P, that's all
we're doing there for now, ordouble quoted, making sure you
take out the comma there and thecomma there. And in the block
J's, we're going to add props tothe functions, arrays, it's a
parameter for the edit functionof props. And then we're just
going to console log props here.And then have this edit props,
props notation, V. Okay, I'mgoing to pull my coffee quickly
while I wait for everyone tocatch up. And then we'll show
you what this does, when youswitch over to the editor.
Okay, so hopefully, everybody'sup to speed with that. And
they're gonna be able to seewhat this does. In the website,
I'm going to switch back to mybrowser here. And I'm going to
go into my post. And I'm goingto remove the block. And I'm
going to turn on developertools. Now, depending on your
browser, depending on whichbrowser you're using. I know
this works in Chrome, and Chromeas developer tools. I know
Firefox has developer tools. Iknow, the windows Edge browser,
which is based on Chrome hasdeveloper tools. I don't use
Safari, but I'm pretty sureSafari has developer tools as
well. There's there's acombination of shortcuts that
opens it. Sometimes if 12 opensit. In a Mac, if I have a look
here, if I go to more tools,Developer Tools is the what is
that that's the option commandlook like off button, whatever
it is, but each browser has adeveloper to some way, it's a
very good idea to have DeveloperTools open when you are
developing with blocks. The onethe one reason is so that you
can log things to the console,and you can see what's going on.
The other reason is, is if thereare any errors, those errors are
going to get logged. And whenyou start developing with
blocks, it's a good idea to openup your dev tools and see what
errors are being renderedwithout you doing anything with
your block so that you candifferentiate between your
errors. And we're now here, forexample, we've got an API
Fichera. This isn't a WordPresserror, this is probably my my
local environment not being ableto connect to some external
service. But you'll see herethere's a jQuery migrate thing
that's been installed. Andthere's an there's the core
separator block that's renderingto the to the, to the console.
So this is the kind of stuff sonow I know if I ever see a
different type of error, I knowit's related to my block. Okay,
if I now add my block to thepost, I should have seen a
console log array. Because I didthat in the code. Now one of the
reasons I might not see that isbecause you're working in
JavaScript, sometimes theJavaScript gets cached in the
browser. And there are a fewways around this. One of the
ways you can do it is to usesomething called browser caching
where you apply it liketimestamp version number to your
scripts and all those kinds ofthings. But one of the cool
things about Chromespecifically, and I'm sure the
other browsers do this as well,is if you have Dev Tools open,
and you right click on your onyour refresh, reload the page
options. So if I right click onhere, there's an empty cache and
hard reload options. And that'svery cool, because now it's
going to clear the cache andthings should start working for
me. So I always have Dev Toolsopen and I always use the empty
cache and hard reload jobs. Andyou're gonna see me doing that a
lot today. Okay, so let's reloadthat. And let's see what happens
if we add that JavaScript block,we should see things logging to
the console. So let's do that.And there we go. Now we're
seeing the JavaScript log to theconsole. I'm going to make my
console a little bit biggerhere. So that folks can see it.
So if we look at that, thatobject we've set up there's the
Edit props that we set. Andthere you'll see it passes the
attributes through to the props.It also parses things like a
client ID, it pauses a contentcontext, it parses something,
insert blocks, a whole bunch ofother things related to the
block. Now, Adrian was askedearlier about an ARIA label. Now
if you don't know what ARIA is,it's related to accessibility.
And you can, as far as Iunderstand that, you can set
those labels to differentproperties to make them
accessible in a certain way. Theuse block props that we use last
week is where that gets set up.So what I also want you to do,
and we're going to kind of diveinto the difference between
props, props, and use blockprops here, I want you to copy
that that line out, and I wantyou to create a second one. And
we're going to say this is blockprops. And then I want to copy
the fact we can't do it therebecause we haven't set it up
yet. So let's take this blockprops var and put this right at
the top here. So that we have itset up. And then we're going to
log about that. Okay, so nowwe're just logging the first
props parameter, which is theone that's passed to the edit
function. And the blocks props.params are variable, which is
the one that we set up bycalling the use block props
React. Okay, if I now refreshthis, now, what I'm going to do
is I'm going to remove my block.And I'm going to empty cache and
hard reload, and I'm going to,as I say, I'm going to be doing
this a lot today. If we then readd it, we should then see two
things being logged to theconsole. Okay, so there's edit
prompts. And there's blogprompts. So let's make that a
bit bigger. And let's make thata bit bigger. And you'll see at
the top of the block props, thatARIA label is being set. So
that's automatically createdbecause we're using use block
props. And here's where we needto spend a little bit of time
understanding the differencebetween the properties of the
block and block props. Okay,now, block props is what's known
as a React hook. And our Reacthook is just a special function
that does a certain bunch ofthings automatically. Last week,
we learned that the one thingthat it does is it sets the
class name. Now we've learned italso sets the ARIA label. It
also sets a data block attributesets a data title, it sets a
data type, it sets an ID. Andall of these things get applied
to the block element, the mainblock element. So if you right
click on your main blockelement, share this text area
here, and you inspect this,it'll take you to the element,
you'll see that all of thosethings we just saw in block
props, I'm trying to make thisso that everybody can see this.
Things like the ARIA label,things like data block, things
like data type, data title,these are all being applied to
that paragraph element, that isthe main container element of
the block. So if we change, forexample, this block to be a div,
which we can do that. So let'sdo that quickly. So what I want
to do is I want to change thisover here to a div element. So
that's all I'm doing. I'mchanging it from a paragraph to
a div. I'm going to save that.And we're going to switch here.
And again, we're going to emptycache and hard reload. And then
we're going to add that block.And we're going to inspect it
again. There you'll see now todo, but it has the same ID the
same ARIA label, the same datablock the same data title,
everything from the block props.So to reiterate, block props is
a special function that does awhole bunch of things
automatically. And it appliesthose things to the main
container of your block,whatever your main container is
that you set it applies thosethings. The props that we pass
to the functions are specificproperties related to just the
function of the block itself. Soit doesn't affect things on the
outer container. But it's howyou can pass things like
attributes around. It's how youcan update attributes. And it's
important to understand thosetwo different things. Later on
in this workshop, we're actuallygoing to pass some of the props
to block props. And we're goingto work with a bit. But it's
good to understand what thosetwo things aren't, how they are
different, and how they interactdifferently and how they do
things differently. You'llnotice that if we go back to the
console, it prompts if you havea look, the name comes from the
block dot JSON exactly as wehave it set up in the block dot
JSON. And as a client ID it hasthe attributes from the block
JSON, it has other things thatit adds on remove and replace,
but it's specific, sorry,clicking my macro, it's specific
to the block. Whereas blockprompts is specific to the outer
element in that block. Andyou'll see it's already created
it basically does it runs awhole bunch of things
automatically and then appliesit to that element. Cool. So
we're gonna pause there for asecond if anybody has any
questions on all of that.Otherwise we will we will move
on okay, they don't seem to beChristians. So I'm going to move
this over here. And the firstthing that I that I want to do
is I want to make this blockeditable. Now, if you come from
an old school HTML world like Idid, you'll remember that one of
the first form elements that youmight have learned on to make
something editable was a textarea. So text area is basically
a default html element that hascolumns and rows, and you can
then type some some data in. Sowhat we're actually going to do
is we're going to set up thetext area in this block. So I'm
going to just comment out theseconsole logs here for a second,
we're going to use them later.So leave them in. And then I'm
going to change the element thatwe're setting up to be a text
area. That's all I'm going to docase, I'm setting up a text
area. And I want to show youwhat that does. So again, I'm
going to remove, going to hidereload. And if I now add the
block in suddenly, it looksdifferent. As you can see, it's
not a paragraph tag anymore.It's a text area. But you'll
also notice I'm suddenly gettingsome errors. And these errors
are not the errors that I wasseeing earlier. And it's saying
Why didn't you use default valueor value on the props and
various other things. Okay, sostarting to give me some
problems, which is fine. But atext area, I can actually edit,
and I can do things to Okay. Sothat's kind of cool. I think,
just by changing the elementsfrom a paragraph to a text here,
I can actually implement a textarea in the editor. And I can
then make some changes to thesechanges won't save though.
Because as you will rememberfrom our code, our code in the
save function is still returninga paragraph. And it's still
using the hard coded string,we're going to get to how we
change that in a second. But Ijust think it's cool, but show
you how that works.
So let me go back to my internalnotes and just change this.
Okay, so we've done thedeveloper tools, we change the
elements cool. Now we've now wewant to get that attribute from
the blog to JSON into our textarea. So there's this cool thing
that you can do in the blog toJSON attribute. And you can
specify a default value. If youadd default here, and then I'm
going to copy out this helloJavaScript world text. And I'm
going to specify that as thedefault value. Okay, so put a
comma in there quickly. So nowit has a default content. And
then because we've got thiscontent, we want to render this
content summary. So let'sactually render it over here. So
because we've got props, propscontains the attributes, and I'm
going to show you how to accessthe attribute. So it's props,
dot attributes. And attribute wecalled content, so it's dot
content. Okay. So we'rereturning the element function,
we're saying it's a text areaelement, it still uses block
props, and then it passes in thecontent that we specified in the
attributes for the block. So nowwe should see, and let's make it
hello JavaScript world. Let'smake it a little bit unique.
Let's say hello, my JavaScriptjust so we verify that this is
what's happening. But now noticesomething else. When we set up
the attribute, we said we wereworking with a pea select.
However, we've just changed thatelement to a text area. So we
need to tell the attribute towork with the text area as well.
And that's where the selectorcomes in. Okay, so here, we can
just go text area, the sourcesdot HTML or the text area,
that's fine as the internalcontent of the text area, but
the selector needs to be thetext area. And that's what this
arrow was telling us over here.If we go back here, it was
saying, use the default valuevalues that are setting the
children because we were settingchildren data instead of a
value. Okay, so we've set thatto text area, we've set this to
text area, we've changed it tothe content of props,
attributes. Let's see if thisworks. So let's remove this hot
reload. And we re add it again.So now we're still getting an
error. So let's see what theerror is. Okay, it's still
saying use the default value orvalue props instead of setting
children on texture. Okay. Now,I've done something that I
shouldn't have done. And I'mgoing to have to check my code
and figure out what I've done.
Prepare, what have I done wrong?Let me go back to my GitHub for
this because I have forgottensomething. So give me a second.
I made some notes about thisyesterday. And it's the rich
text I
think it's because I've stillgot the so sit, try that
takes it away Nope, stillgetting nearer. Huh? Use the
default value or value props setof sitting children on text area
okay, so this is where lookslike you do not need props. So
you need props to get thecontent. But I have a feeling,
it's because I'm passing it inas children and not as as I
remember. Okay, let's go back tothe documentation, because
documentation is nice to lookat. And let's find the plane.
Okay, here we go. So when you'respecifying something other than
a paragraph, or a div, sosomething that is editable, like
a text area, the way it works isyou need to pass the content as
the value in block props. Andthis was something that I got
stuck with on Tuesday. So I'msurprised I forgot it today. So
what we're going to do then iswe're going to grab this code
here. So if you if you'refollowing along, and you've got
this plain code open, scrolldown to the edit function. And
you'll see it says rich texthere, which we're not going to
use now. But grab this object,assign code here. So object
assigned blood drops all of thisdown to here. And we're going to
use that. And I'll explain in asecond, why this is necessary.
So we're going to take that outthere. And I'm going to make
this on a new line just so wecan see it. And we're going to
pop that over there. I'm goingto pop that in there. And I'm
going to explain what objectassigned means in a second, the
tag name, we're going to maketext area, we're going to leave
out the unchanged content fornow. We'll put that back in a
sec. And the value will be theprops. No, not that one. Props
dot attributes dot content.Okay, so that's what it looks
like. So we're updating theelement call, we're passing in
the text areas, the first thefirst variable. And then in the
second area, what we're doingthis object assign business,
passing in blog props, and thena new object, which has a tag
name, which we don't need a butI'll show you what it does in a
second. And then a value. Okay,is this on the attributes page?
I don't see this code. Yes, ifyou have a look on the
attributes page. So I'm going toscroll from the top. So this is
the introducing attributes in itas both fields doc, not the not
the attributes. So not theattributes in the Reference
Guide. But the introducingattributes editable fields in
the How to Guides. So the firstone that we looked at, I'm going
to copy that out, paste it inthe chat so that you have it.
And then if you scroll down tothe example code, and you click
on the first example and youmake sure the plane option is
highlighted, and scroll downabout halfway, you'll see the
edit function with the props.And then further down you'll see
the return elements rich textobject assigned pot Do you have
that?
Anybody needs to catch up. Weneed to slow down. I'm very lost
today. Okay. Let's go back astep. Adrian, do you have no
that's fine. I want to I want toI want you to catch up with us.
Do you have this at least? Doyou have this in your in your
edit function? You're welcome tounmute if you if you find easier
to talk. Okay, so you've gotthat. Okay. Then open up the
link that I just sent you. Youdidn't get my errors really? Am
I the only one getting errorstoday? Okay, so everybody else
did they see did they not seethis error on this side? That's
interesting.
That's interesting. I wonder ifthat's is the version of
WordPress that I'm running? Whatam I running? Get the cache that
shouldn't be that. 6.1 Yeah, Ithink I'm running 6.1 as well.
That's interesting. I'm seeingI'm seeing errors that other
people aren't seeing. I'm doingsix. I'm running 611. So that
might be why it might be anupdated 611. Let's spend some
time figuring that out. Let meinstal the habit, I downgrade to
hang on. There must be a way Ican downgrade. I could do this
on the command line. But I'mlazy today.
I've got a core core rollbackplan. It's called
core. Yeah.
So you're trying to do Yeah,call roll back on there was
right there.
Okay, it's taking its time.Yeah. It's an Andy fragen
plugin, why am I not surprised?That's interesting that nobody
else got those errors. So let'sactivate that it's rolled back
this version of core, Alvaro, wemight have, we might have
uncovered a bug that needs to beloved. Okay, let's roll back
this 1261. And let's see if Iget better. Still six one.
Perfect time for a sip ofcoffee. There's nothing, there's
nothing that wakes you upquicker than a cup of coffee in
the morning or an error that youdidn't expect in a live
workshop. Now, it looks like I'mprobably look more or less than
everybody today. Let's let thisthing finish. It looks like I'm
running sixth one. So let's goback to my posts. Let's go back
here. Let me switch on devtools. And let me clear cache.
Let me check. That's my oldplugin code. That's what I want.
Excellent. Let's add the plugin.I'm still getting that error.
But other folks aren't gettingthis error. That's interesting.
So So those of you have your devtools open, you're not seeing
this use default value error. Iwonder if it's a plugin that I
have installed. Let me activateall my other plugins. That one
as well. But over here, I'mgetting the same error. Okay, so
as I don't have the Gutenbergplugin installed. So maybe the
so Adrian, those of you whoaren't seeing the error, do you
have the Gutenberg plugininstalled, maybe disable it and
see if you're getting becauseyou should get there. It's it's
my understanding of things. Iwant to make sure we're all if
it takes, if it takes thatamount of time today, I want to
make sure we're all on the samepage at least. And then we can
dive into why the error happensand what's going on. So let's
make sure everybody's on thesame page here. Yeah, you
definitely you definitely shouldbe getting there. If you're not,
there, no extra plugin installedonly the one we were making. So
that's interesting. Some folksare getting there, and some
folks aren't. So So we'll savethis. There should be an error.
I wonder if it's because let mejust check with my debug
settings. So those of you whoaren't seeing the error, can you
do me a favour? And can you gointo your WP config file and set
the WP debug variable to trueand then also include this
define script debug to true thatmight be why that that might be
why you're not seeing there. Andthat might be why I'm seeing it.
Because when I develop I leavedebugging on all the time so
that I see any possible errors.So those of you aren't seeing
there, open up your WP hyphenconfig, and then run a bad line
82 It'll probably be defined WPat Vogue would be false, change
that to true. And then add thisone after that. I'm going to
copy this into the chat. And ifanybody who's not seeing that
error could try that out andreport back what you're seeing.
While you're doing that I'mgoing to turn these things off
and see if the error issuppressed. And that might be
why some folks are seeing it andsome folks aren't.
I see I'm not seeing it now. Sothe error is being it's possibly
being said Press for some ofyou. So for those of you who
aren't seeing it, if you if youset up those, those debug
variables or constants, and thenquite hard refresh and add this
file, you should then see thaterror
if I do this workshop, again,I'm gonna make that part of this
workshop as well. I'm gonna hangaround and wait while everybody
tries that out. And let me knowlooking forward to getting your
feedback. pack a bag yours.Yeah. So if you scroll up at the
top, you should see the samemessage that I got, let's
actually remove and odd reload,and re ad. So you should see all
of these and right at the top ofthat of that error, you should
see something along the lines ofuse the default value instead of
setting children. So if you'reseeing that, give me a yes, give
me a second, give me a thumbsup. We're all on the same page.
And then we can move on.Excellent. I'm glad folks that
are seeing that. Okay, so let'sactually take a break and talk
about that. Whenever you'redeveloping for WordPress, I
highly recommend having yourdebug constant switched on.
Because this what you see theproblem, the problem with errors
is that there are differentlevels of error. There are
breaking site errors, which youalways want to see. But then
there are errors that are notgoing to break your sites and
functionality might still work.But it's not the recommended way
to do things. And that's thisone, we saw now about using the
value instead of the children.And I'll explain what all that
means when we get back to thecode in a second. But it'll
still work. The problem with theproblem, and those are more sort
of warnings, you also getdeprecation errors. So something
has changed in either PHP orJavaScript or the framework or
whatever. And it still works.But the problem with the
application errors is that mightstop working. So it's better to
stop using those things. And theproblem with warnings as well as
warnings are saying, hey,something that you're doing kind
of works, but it reallyshouldn't. And it could lead to
other things you're not awareof. So whenever you're
developing with WordPress,always have your WP debug
constant set to true and that'lllog all PHP errors. And always
have your script debug set totrue. And that'll log all
JavaScript related errors. Forthe PHP related stuff, you could
also define the followingvariables which I like to do. I
like to do web, debug, debug,debug, display as false. And
then what that does is that logthere is better than suppress
them in the browser. And then Iset WP debug log to true. And
what that does is that log themto a file in the WP content
directory called debug dot log.It'll send them all there. So it
means while you're working withthe website, if you make a PHP
error that can cause your siteto break, everything else will
still run, but the error willget logged at least. This is
also an I'm sure ovvero who'swhose happiness engineer at
wordpresser. Org will appreciatethis bit of knowledge. This is
also a way to troubleshoot widescreens of death and other
related issues is make surethese three things are enabled,
run the site and then check thelock. I'll throw my right that's
probably one of the first thingsyou tell folks to do when they
when they have a support ticketwith a white screen.
Yeah.
Okay, cool. All right. So we hada little bit of a detour on
logging. Now. Let's get back towhat that error means and why
the code was wrong. So if wehave a look at the error, it
says use the use the defaultvalue or value props instead of
setting children on text area.Okay, so let's talk about what
that means in a second. So whatI'm gonna do in a second now is
talk about now, I'm going toopen up a very simple HTML file.
So we can dive into this,because it's important to
understand, in fact, let's justdo this one here. So this is
just the readme in, in theWordPress instal. Now, if you've
worked with HTML for a whileHTML DOM, the document object
model, you will know that youcan do things like in
JavaScript, you can say getelements by Id get elements by
name. And then you can do thingslike get children elements. So
if we have a look at, forexample, this ordered list here,
if that is the parent or toplevel element, the children
elements of that elements areall the list elements. But what
isn't commonly known is thatchildren have for example, this
h2 is the HTML text inside h2 isalso the children. Now when
you're working with things liketext areas, text areas are a
special type of element thatallow things to be changed. So
you don't let me actually justshow you, for example, With an
input an input field, youtypically have a value in an
input field, you don't typicallywrite it like you would an HTML
element, it has a valueproperty, and then you update
the value property. If we have alook at, let's go to Indian text
area, let's go look at theofficial documentation on
Mozilla network, the text areaelement. And let's just find an
example of a text area are goingto show us one Yeah, yeah, there
we go. So a text area. Nowhere's what's interesting, it
takes the area in HTML, youwouldn't be able to specify
children because there's textinside the element. But in the
React World, or in theJavaScript DOM Document Object
Model world, you would ratheruse the value of the text area.
So that's what that error istelling us. And that's why the
code still works. Because it isacceptable from an HTML point of
view, just to say the childrenof the text area is the text.
And it'll render that properly.But because you're working in
this JavaScript world, whereyou're working with values and
attributes, and all kinds ofother things, you would rather
specify the value of the textarea objects. And that's
something that folks often getconfused with when they start
working with what's known as theDocument Object Model. Or
there's another term called theShadow DOM. For these JavaScript
concepts. It's sometimes how theelements work in the DOM, versus
how they work just in a plainHTML file is slightly different.
So that's effectively what thaterror message means. And what
it's saying is use either thedefault value or value props of
the text area, instead ofsetting the children. So when we
do this over here, let's go backto the code. If you you might
remember, when we looked at thisCreate Element function earlier,
it said the first, the firstparameter is the element that we
want to create. The second oneis an object of data that we can
pass it. And then the third onewas the children of that
element. And what this code istelling us what this error is
telling us is we're setting thechildren, but it's saying rather
use the value, that's thebetter, more correct way of
doing it in this JavaScriptReact T type framework. That's
another thing to note is thetitles of these workshops are
right blocks without usingReact, we are actually still
using React in the background.The Block Editor is written
using React, everything thatwe're working with is using
React, we're just interfacingwith those React elements and
React components in plainJavaScript. But this creates
elements. Hook is a React hook.The the use block props hook is
a React hook. So we're notphysically writing React code
ourselves, but we are interinteracting with React, which is
why we get these interestingerrors about using values versus
using children. I hope thatexplains it. It took me a while
to wrap my head around it. Ifanybody is still not sure about
that, I do recommend going andreading about how React DOM
works, the document object modelversus HTML layouts. But that's
basically what the error means.So what you have to do now if we
go back to the documentationthat I shared with you earlier,
and this is another reason whyI'm doing these workshops,
because for the first time I sawthis code, I was like, what does
that mean? What are we doinghere? Effectively, what we're
doing is object assign, is verysimilar to the PHP array merge
function, it basically says,take an object, take another
object and merge the twotogether. So in this case, the
first object is the block propsthat we got from us block props
that React, then we're passingin another object, and we're
sending in a tag name, we'resending in, in this case,
unchanged, we'll talk about thatin a second, don't worry. And
we're giving it the value, whichis what that error is telling us
to do is set the value of theelement instead of the child. So
let's copy this out. And let'sgo back to our code. And let me
just make sure that my debuggingis on Yes, my debugging is still
on. And just to make this easierto read, I'm going to protect
area on its own line on my blockprops on its own line. And I'm
going to take away the content.What you could also do is you
could do something like this,you could say, I think this
works, you could do somethinglike that, merge them together
into blood props, and then useit. But the easiest way to do is
just to basically do it in placeof blood props. So what I'm
going to do is that I'm going toleave out the tag name for now
I'm going to leave it unchanged.For now, we're just going to
pass in the value. And the valuethat we need to pass is the same
content that we passed earlier.So in other words, the props,
attributes content like thatexactly the same as we did
earlier. And then we'll do alittle bit of formatting for my
dad so it looks a little bitneater. And this is what you
should end up with Okay. Iseverybody up to speed on that?
Do I need to limit Let me take abreak. So that flex and catch up
if they like, if anybody needsme to stop or whatever, let me
know. Otherwise, if you're happyfor me to continue, then give me
a thumbs up. We're ready to go.It is administration still
behind? Okay? Are you justcatching up with the code? Do
you need me to wait?
Cool, that's no problem, we candefinitely wait.
That's why it's called let'scall it not Jonathan codes.
While Adrian is catching up, Iwill, Adrian Sorry, I keep
saying that wrong. I will alsomention that this whole concept
is something that I struggledwith a lot when I first got into
Block Development, how to setattributes, how to pass them
around how to update them, howto change them. And my plan
today for today's workshop wasactually going to be to assign a
whole bunch of attributes and doa whole bunch of things. And
then I realised maybe we shouldjust do one. And I'm so glad we
did. So we might not actuallyget to where we want to get to
this by the end of thisworkshop, and we might take some
of it, move it to the nextworkshop. And that's also okay.
Because it's important that weunderstand how this works and
what it does. Before we canstart moving on. Everyone's up
to speed now. So that's great.So let's see now, what we have
on the front end. So let's goback over here. Let's remove
this. Let's do another hardrefresh. Okay, let's add the
block. Now we should see noerrors missed, I'm still getting
an error, why am I still gettingan error? Okay, Aha, there is a
little bit more understandable.So you should see a similarity
that which is good. We'll getinto the onchange in a second.
But basically, that's the onlyerror that I'm seeing at the
moment, which is an error that Iexpect. So that's great. Okay.
So I've got my text area, andbusy parsing the content of the
attributes or the the value ofthe text area. I want to show
you, is anybody else seeing thesame area that I'm seeing?
Because if you are that's good,that is what we want to see.
Does anybody not seeing that? Iseverybody everybody happy with
what they're seeing? Okay, samearea. That's excellent. That's
what we want to see. Everybody'sgetting the same error by the
looks of it. Good. Okay. Now,what that error is telling us is
that we need to specify an ONCHANGE handler. So again, in
HTML land, let's go back to anHTML file. You might remember
that it would have been possiblein old days, you had this
onchange event that you couldspecify on any kind of input
value or text area. And then youcould pass it a JavaScript
function call or a jQuery orwhatever. And basically, what
happened is, as soon as thevalue or the internal HTML of
that element change, it wouldtrigger that JavaScript code.
Because we have got a text area.And because we're passing it a
value, React is saying to us,Hey, you're passing a value. And
I'm going to assume you're goingto want to do something with
this value. So would you mindpassing in an unchanged handler
as well, again, it doesn't causethe block to fail, I can still
see my block can see my texthere with the content. It's just
giving me a warning and going,hey, you know, it's actually
being nice. It's being friendly.It's saying, Hey, you might have
missed some things. So if wehave a look at the the example
code from the documentation,we'll see there the unchanged
handler is specified. And lookat the difference in regular
HTML, that unchanged is usuallyall lowercase. I think camel
case does work, but it'stypically all lowercase. But in
in React land, you need tospecify it like this as on and
then uppercase C for unchanged.So we copy that out. And we're
going to update that in ourobject assignment and just make
sure you're inside the objectassign. Now, again, it doesn't
matter too much where you putit, because this is just an
object. So I'm going to sayunchanged. And I'm going to
specify an on change contentfunction. I can call it whatever
I want. But then I actually needto create that function. So if
we pop back over to the code,you'll see at the top here,
there's a function calledunchanged content. It accepts a
new content variable. And thenit calls the set attributes prop
set attributes, content, newcontent. And you might remember,
when we echoed the promptsearlier, there was a set
attributes value. And that's acool default value that exists
on the blocks, props or theproperties and allows you to
update the property. So whatthat effectively does is when
the text area changes, it'lltake that new value, pass it to
this unchanged content function,the new content will be there.
And then it'll say, set theattribute Use the specifically
our content attribute that wewant to set. In other words,
this one that we specified hereand set the new value of content
to whatever we're passing to it.Okay, this is going to break.
And I know why this is going tobreak. And I'll explain why in a
second. But for now, that'swhere we want to be. So we've
set up the unchanged eventhandler, we've told it to
trigger unchanged content, thenwe created on change content,
say except the new content, orwe can call this anything we
want. We can call this just newif we want. Or we go new
underscore, content, whatever.This is just how we define our,
our parameters. And then withthat new content, we want to say
take the set attributes functionfrom props, and then update the
content attributes with the newcontent. Okay. I'm going to
pause there if anybody needs tocatch up. Otherwise, we're going
to test this out and we're gonnasee what happens.
So let me show you what happenswhen I run this. Seminar, remove
it on a hard reload. Let'sreload that day. And let's add
our block. Okay, so now we'renot getting errors when we add
our block, because it's got avalue that it's happy with. And
it's got an unchanged handlerthat's happy with. So that's a
good first step. But watch whathappens when I change this
blocks on all I'm gonna do isremove the D suddenly changes to
this object, object string. Andif you're testing this on your
side, you should see somethingsimilar. If you don't, please
let me know. But if you see thesame, give me a same error, or a
thumbs up or or whatever in thechat. Let me know that you're
seeing so Okay, good. So we'reseeing the same. Now, the reason
this is happening is because thetext area is not a specifically
React element. It's just aregular HTML element. So when
the unchanged handler fires, itpasses not the content but an
event. And that's not somethingthat you would necessarily know
about the text area element. Andit's one of the reasons that you
wouldn't use the text areaelement, you would use a React
component, in our example, therich text component. Okay, so
let's take a step back. If we goback to the documentation,
you'll see it talks here aboutcomponents and the rich text
component. Okay. So earlierexamples, we worked with using
the Create Element function tocreate DOM nodes. But it's also
possible to take thatfunctionality and put it into
reusable components. And this isone of the very cool things
about specifically React, butalso about the Block Editor is,
instead of just using a textarea, which looks awful, we can
implement the rich textcomponents. Now the rich text
component, if you open up thisrich, I struggle with all of
these consonants. If you open upthe rich text component link, it
takes you to the reference guidefor rich text. And effectively,
it's just the component that isrendered when you render a
paragraph tag in the BlockEditor. So sorry, a paragraph
block in the Block Editor. So ifI go back to remove this video
at the way Yeah, I'm just goingto remove my block. If I just
add a regular paragraph, so justa paragraph block that
effectively implements the richtext component, which allows me
to do things like type words, ifI can spell them, but it also
allows me to do things like set,bold, or set italic, or specify
a link. That's all happeningbecause the paragraph block
implements the rich textcomponent. And that's the
perfect block for us to use inour basic JavaScript block.
Okay. Because as your as your asyou'd have agreed with me
earlier, that takes area that weuse, let me just adequately
where's my JavaScript block?Here it is, doesn't look great
at all. It's sitting off to theside somewhere, there's no
formatting options, I can justmove it up or down. So instead
of writing a whole thing, I justreuse a package that WordPress
makes available to me. Okay. Sothe rich text reference image,
just find the package. I thinkit mentions that here. Rich text
component is part of the BlockEditor package, right. And if
you remember when we looked atthe code, we were already
implementing the Block Editorpackage because we want to use
use block props. So that meansyou don't have to change any
dependencies. It's already partof the Block Editor and most of
the core components are part ofthe Block Editor. So what we can
do is we can include the richNext component into our so we
don't have to worry about allthis because this is all done
already. We can do this overYeah, so we can say var richtext
is Block Editor reg x. So we canjust put this at the top here,
like that, okay, and that'llmake rich text as a component
available to this wholefunction. You'll notice the
other thing that we're doing isthey're they're moving use block
props to the top here as well.That's also one way you can do
it, actually like that. So I'mgoing to do that now as well.
And I'll give you some time tocatch up. And what that does is
that allows us to take away thisyear, because the Block Editor
variable that we set up iseffectively now available in the
global scope. So it's there.Okay, so the changes I've made
so far, I've added the rich textline. So var rich text is the
rich text from the Block Editor,this needs to be in that same
uppercase format as it isbecause that's what the
component is to find us. Thiscan be whatever you want, but I
like to keep them the same. Andin the same year, this VAR use
block props is also from theBlock Editor. So it's basically
putting those those objects intomy into my function. And they
want to done is I've changedthis line from instead of saying
Block Editor use block props, Ijust said, just use block props,
because it's in the globalscope. And then in the severed
and the SEC, just use blockprops set, those are the changes
that I've made so far. Thereason I do that is it just
makes it easier to work with.I'm specifying the block props
in one place, and then justcalling it wherever I need,
specifying which taxpayer, Ineed it and then just calling it
wherever I need. Okay. Onceyou've got there, somebody gives
me a thumbs up or a saying we'regood to go before we implement
the rich text editor.
Hey, Alexa, good to go.Excellent. So now we can
implement rich text. So there'sa couple of changes we need to
make. First change we make is wetake out the text area here. And
we replace it with rich text.Okay, that's the first change.
We don't need to necessarilymake that change in the save.
But I'll show you how you canuse rich text in the save in a
second. But we can just leavethe Save as it is for now. The
other change we need to make inthe blog that Jason has, we're
no longer using the text areaselector. We're using rich text.
Now, I want to show you whatRich Text renders so that we can
understand what we must changethat. So if I inspect my rich
text here, you'll see thatscroll up, the rich text just
actually renders a paragraphtag. So that's cool, because now
we can set the source back towhatever it was selected back to
P, and that'll work. So in theblocked JSON, we can specify
this beam back to A p for theparagraph tag, because rich text
is basically just implementing aparagraph tag with all that
other cool functionality. Okay,so your your content attribute
is still a string type, becausewe're still working with string
content. Still a p tag, thedefault is still the same. In
the block JSON, all we've doneis replace the p tag here with
rich text. The rest should alljust work. Okay, so let's see
what happens. So again, let'sremove these extra blocks. Let's
do a note and if that one's toohigh refresh, reload as it calls
it. And then let's implement ourJavaScript block. Okay, so
there's our block. Now it looksthe same as it did when we first
started, you remember, it hadthe green because it was just a
paragraph tag. So the stylingalso works, the block props are
still being used. So it's stillthe same class name. But you
notice, suddenly, I can dothings like I can set things
bold, I can make things italic.So because I'm using rich text,
instead of a plain paragraphtag, that's all working. I'm
going to switch back to myconsole, there are no errors. So
that's excellent. I'm going tomove this over to the side so we
can see a bit more of thescreen. And if I start making
changes, it's doing some thingsin the background, okay, because
I've done the set attributes andall of that. So that's great.
There's no errors there. Butwhat happens when I preview it's
still the original content. It'snot using the attribute that we
specified, so we need to changethat. Okay. So if I go back to
my code, now we start thinkingabout, well, how can we get
those properties that well, wecan do it exactly the same way
we did with edit function, wecan specify the same props
attribute there. And understandyou're editing your save
function, they're always goingto receive the properties always
every single time. So you putthem in and they will receive
whatever's in them, they will beavailable. If there are no
attributes, if they won't beattributes available. If you set
the attributes they will beavailable. Okay. We don't need
to do things like unchangedcontents and all of that. So we
can just leave it as a paragraphtag if we want to. We can leave
the blog props if you want to.But we cannot update this to be
the blog props, attributescontent. Okay, and that should
work. So let's see. So again, weremove me hard reload. And let's
add it. Okay, that's working.Let's update the content so that
something actually gets saved.And I'm going to show you just
in the background, how thisworks. And now let's preview
this. Hello, JavaScript world.Yay, it's working. Okay, so how
can we validate that this isworking. And the one thing that
I like to do is I like to usethis edit props here. And what I
like to do whenever I'mdeveloping is I like to just
have a very simple console log.Sorry, I'll just recode it. I
like to have a very simpleconsole log here. And I just log
props, attributes, such as theattributes of the props of the
blocks properties. And I like todo it in an object so that I can
see whether I'm in the edit orthe save. And I like to do this,
I'd like to do edit attributes,what entity hours or whatever
you want. And then I pass in theattributes. And then I like to
have in the Save as well. And Ihave a save a TTRS. And it logs,
props, attributes. And thenwhenever edit fires, and
whenever save fires asfunctions, I will then see that
data in my console. So I'm goingto leave that on screen while
you catch up if you want to ifyou want to put that in your
code as well. When you're readyto go, give me a give me a
thumbs up or a good to go. Andthen we'll go and see what this
does on the front end. I'm soglad I didn't try and do more
attributes today because we runout of time.
Hey, friends got it. So I'mgoing to going to move on from
here. So let us remove thisagain. And it has hide reload
again. And I want to show you inthe console every time the edit
function and every time the savefunction fires so you can
understand what's happening inthe background. So let's add the
block, and you'll see the editfunction fires. And then every
time you make a change, you seethat every time you make a
change, edit fires. And so everytime it fires, let's go back to
the code. Every time edit fires,the unchanged content fires, it
takes the new content runs propsattribute set set attributes
function and update to thecontent with the new content
every single time. And then onthose as well. Sort of
periodically, when you'reworking with the edits, the save
function will fire. So it's notevery time you edits. So if I
edit one that's edited, edit,edit, edit an hour wait. Then
save files. So you see thatsaves not happening all the
time. It's happening like one ortwo seconds after the last edit.
So it actually waits. However,when you hit Preview, it also
saves and renders it. And youcan actually see those changes
get made. And you'll see saveand it'll just fire it again
just by themselves. So there'slike a timer in the background.
It's just checking, do I need tojust keep saving, keep saving
and off we go. Okay, so that'show it works. Every time you
make a change it, it's firingit, it's firing it, it's firing,
it's making those updates,updating the props, and then
save fires and writes it to thedatabase. Okay. Cool. I'm gonna
stop there. If there are anyquestions around any of that.
There's a few other things I dowant to cover today. It's just
kind of wrapped cleaning up afew things, making things a
little bit better, a little bitmore standardised. But are there
any questions around everythingwe've covered today? The
functions that we'veimplemented, how we've
implemented them, that anybodyis not sure of, now's the
perfect time to ask before wewrap up for the day. Okay, I
don't seem to have questions,but if you think of them, please
do paste them in the chat whilewe're going. Couple of other
things I want to show you. Thisprops object contains both
attributes and the setattributes function. And every
time we want to use it, we haveto go props that attributes and
props that said attributes yada,yada, yada. There's a nicer way
of doing things and it's calledLet me find the the document
link for you. When I did this,we just by the way, what I did
this week was the firstResources tab has all the
WordPress documentation. And thesecond Resources tab has all the
Mozilla stuff that we weretalking about. And the first one
is the object assign one there.The first one is the D
structuring assignment. So letme show you that. So what
destructuring assignment does isallows you to distract or take a
part and objects, and pull outcertain pieces of that object
and make it available to yourfunction. So let me show you
what that means in the code. IfI open up an object notation
here, and then I just typeattributes, comma, set
attributes, and you'll see thatmy code when my code is, is
quite clever, it's actuallyexpecting those things. What
that's basically doing is it'sbasically saying, assign the
attributes from the props to theto this attributes variable in
this function, and then assignthe set attributes from the
props to the set attributes inthis function. So now, I can
just remove that and just echothe attributes. And I can also
just change that to setattributes, then it does the
same thing. It just means lesscode on your screen. And you can
D structure any object like thisin in JavaScript. So if you're
passing any object to a functionas a parameter, you can destruct
it in this way, by justspecifying the object notation,
and then the specific items fromthat object that you need. This
is something that has only cometo PHP very, very recently. But
JavaScript has had it for a longtime. And it's one of the things
that I like about JavaScript isthe fact that as long as you
pass objects around, then youcan distract them nicely like
this in your functions. So thatwas the one thing and then this
also changes here, because I'vealready got attributes, I can
just change this to attributes.And that's perfect. And then I
like to do the same down here, Idon't need the set attributes
function in the safe, becauseI'm never going to update those
attributes. So I can just goattributes there. And I can just
change this to attributes there.And do that it's just nicer and
cleaner and easier to work with.So that's the one thing I want
to share with you. The otherthing I wanted to mention is
that you'll notice that in thesave function, we're just
returning a P TECH. But if youhave a look at the example code
in the documentation, sorry, myZoom has just taken off my
screen, and I can't hit my tabsnow. So let me wait for it to go
away. Because the bigger wasn't,yes, you'll notice the save
function in the example codeuses the rich text content,
instead of just rich text. Andso that's that's a good
recommendation to do. So insteadof just the p tag, let's update
that to rich text content. Andeffectively, that's just the
content of the element, whichwill be a paragraph tag anyway.
So it's effectively the samething. But because we're using
rich text here, we have data touse rich text content here. The
other thing you'll see is thatit's assigning the value and a
tag. Now the tag name is a, I'vegot I've got the doc for that
year, it is the element. The tagname is a specific attributes on
an element. And it basicallyallows you to visit there's a
JavaScript function called Getelements by tag name. So instead
of having to those of youremember, we used to do IDs and
classes, and then we say getelement by ID, or get element by
class, you can also do getelement by tag. So that's
essentially what that's doing.So it's a good thing to follow.
So it's also setting up a tagname in the in the block prop.
So it's a good idea to do that.So let's pop that in there. In
fact, we'll just do the samething over here, do the same
object assignment because it isthere. And we can take out the
children then add. What'sinteresting about this is
because we're using the richtext element, the rich text
element is effectively aparagraph. So we could just
assign the children. Butapparently, it's better to
assign it as the value not thechildren. So that's why it's
recommended to do it in thisformat. It all will still work
the same. It won't give you anyerrors as you saw. But if you're
using the rich text component,it's recommended do it in this
format. So we don't need onchange. We just need the tag
name and we just need the value.Okay, and let's just test that
all still works. So let's goback and remove this. And let's
do a reload and let's add itOkay, so there's my edits,
attributes. I'm still seeingthose which is great. If I do
that, I'm still seeing that it'sstill doing what it needs to do.
The Save should fire soon. Acouple of seconds to save
doesn't really save as fired.It's to a preview. Was it Just
Hello, my JavaScript Hello, myJavaScript that's all working.
So it's all working great. Okay,so the last few things we did,
they were just a little bit of acleanup. Little bit of a,
there's multiple ways to do thesame thing in every programming
language. This is more therecommended way. So I didn't
want to leave you without doingit the recommended way. But
that's how we can applyattributes. Now, just as we've
done that, we can apply multipleattributes. And next week,
that's what we're going to do.So my goal, guess what it says
React React Create Element Typeis invalid expected a string.
Everything is working with thisis coming. Prepare. React Create
Element Type is invalid. So thatsounds like one of these returns
where you're using the elementfunction has a bagginess. Speak
to the string. And I just checkis your attributes look like
this? So the type of string theselectors P and the default as
the default value?
That's good. Then in your Jas,is that what your elemental your
first element looks like in theedit function? So it's got the
rich text? String. Okay, that'sgood. Okay. Then let's have a
look at your so can you copy outyour block js code the whole
blockchain as well. Let's seewhat that looks like.
So what I what I can say isthis, it's always difficult to
debug these issues in aworkshop. So typically, props of
obstacles unchanged newcontents, that that's fine eel
rich textures on block props, Ican pee on change and change
content. It looks good to me,let me just copy the search and
see if there are errors there. Abit a bit of butter. Remember to
grab the edit function easier ifI just sit in front of me wonder
if I should just live anotherlevel. I love live coding this
kind of stuff. Okay, so what I'mgonna do is I'm going to comment
up my edit function and see if Ican get that error with your
edit function. And let's grabyour save. Let's do the same
thing. So save there. And it'spopular saving here. A prop save
blood props use blood props.Unchanged new content that looks
good Rich Text Block props.Tagname unchanged on text
content. Edie props attributescontent that looks fine save
props. Is a rich text content.Let's just clean this up. Props,
attributes, okay, so there wego. Let's see what this does.
Closed captioning is probablystressing with the fact that I
was mumbling under my birthday.It's realised that it's at it.
Okay, so I'm not getting anyerrors with your edits and save
code. So it could be somethingelse. It could be that something
is not set up correctly up top.Yeah, maybe. So you want to just
confirm that you've got all ofthese things set up, and that
your function has all of thosethings. But the code that you
just sent me works perfectly onmy site. So it tells me there's
nothing wrong with your code.Maybe it should be value. It
can't just be this have youtried just clearing your cache
that's for no reason. Let mejust do this.
Attributes This is fine propsattributes Tagname on change All
looks good to me my friend butagain Okay, there we go often
that often that's the problem.And that's why I always carry my
cache when I made it. That'sgreat. I'm glad we were able to
find that. Yeah, I'm not sayingI'm not, oh, here we go, what do
you create element type? Here wego. I'm getting this now. So
let's see what that is.Expecting a string for building
components or class function forcomposite components we've got
undefined, you'd likely forgotto export your component from
the files to find it. Thissounds to me like it's error
with Create Element itself. Idon't think this is a problem
with your code. This may or maynot be a bug. Just want to see
something. The fact that it's awarning, I wouldn't worry too
much about expected a stringtype isn't valid expected a
string? That's interesting. Iwould say that, to me, that's
not your code is the problem. Itlooks like there's maybe an
issue with Create Element orsomething like that. But from
what I can see your code islooking good. So I wouldn't I
wouldn't stress about that toomuch. I might dig into that
after this and see if there's abug somewhere, maybe in the
Block Editor or something likethat, that could be causing
this, but it's a warning, not anerror. So I wouldn't stress too
much about that. Okay, awesome.Let us just go back to the code.
And what was I saying somethingbut I forgot an hour it was it's
completely stopped me. So I'mgoing to call it a day. So yes,
oh, yes. That's what I wastalking about what we're going
to do next week. So next week,the plan is we're going to add
additional attributes and thoseattributes we're going to use to
replace the styling. So I'mgoing to add an attribute for
background, for colour and forpadding. And then what I want to
do is I want to actually have ifwe look at that block click on
here, I actually want to havesome me close dev tools. So we
can see we were talking about Iwant to have some settings in
the sidebar, in the sidebar forthe block, where we can actually
have a colour picker thatchooses the colour for the
background, and chooses a colourfor the text and chooses the pad
slider for the padding. So thegoal here is to show you how to
add additional attributes, howto use existing toolbar
components. To apply thosethings. I was going to try and
do that today. But as you cansee, we've already gone over an
hour and a half. So definitelynot enough time to do that. Once
again, if you are following thisafterwards, if you're watching
this on WordPress TV, this codeis available on a repository in
my GitHub profile. So everyevery step of this workshop that
we're doing, I've got set up ina repository. So you can just go
to my my GitHub, and it's thisWP learn JavaScript repository.
I'm going to copy this link outin the chat, some folks have it.
And I'll make sure that I add itto my slides, because I don't
think I did. So I'm going to dothat now. And then I'll re
upload the slides for the forthe recording, but you can check
out every step of the way. Sothere's the first step will be
created the basic block, thesecond step will be added the
style sheets, the third stepwould be now to date the
attributes in the rich text. Andthen as we go through, it'll all
be there. That is my bid fortoday. Thank you all for joining
me, I hope that this workshophelped you understand how
attributes work, how to passthem around in the block. It is
to me it is one of the mostdifficult things to learn about
blocked development. So if youdidn't get it today, I recommend
watching the workshop recordinglater, I recommend going through
the code documentation. Irecommend reviewing the code,
using console log to outputthings like let's go back here,
the props, the block props, thenew content in this function,
you could do a console log forthe new content see that coming
through. So you understandexactly what's happening.
Because it is to me one of themost difficult things about
working with with blocks whenyou're used to PHP where the
state doesn't change muchbecause it's you know, it's run
from top to bottom and then itfinishes. In this JavaScript
world. The props are movedaround, they're updated, they're
changed all over the place. Soknowing how all this works is
very, very important. As I saynext week, we're going to do
some more attributes because asI say, this is a good concept to
cover. We're going to do somecolours and some styling and
some padding. So I do lookforward to doing that with you
all next week. We've gone fiveminutes over time, so I
apologise for that. But thankyou all for joining me into Are
the rest of your Thursday andthe rest of your week
thank you bye everyone