Web Standards

?Build a realtime polling web app with Next.js

Css Tricks - Tue, 05/29/2018 - 4:00am

(This is a sponsored post.)

Learn to build a webapp that accepts user votes, using Next.js and Chart.js. Users can vote for their favorite pet, and the results are displayed in realtime on a graph in their browser using Pusher Channels.

Direct Link to ArticlePermalink

The post ?Build a realtime polling web app with Next.js appeared first on CSS-Tricks.

Linkbait 40

QuirksBlog - Tue, 05/29/2018 - 1:38am

A CSS-heavy edition. I’m doing research for my possible new book, and I need to know more about what people don’t like about CSS. So there’s a lot on that topic.

  • The Front-End Tooling Survey 2018 - Results. Which front-end tools are used most, and are best-known? Personally I’m most interested in the CSS tools the article opens with, but there’s also JavaScript, where Vue overtook Angular.
  • CSS: the bad bits. Starts with the global scope, of course. Joe’s solution of choice is BEM. Agree or disagree with him on the solution, CSS global scope is not always good.
    Continues with many more useful notes. Very useful for understanding what JavaScript developers dislike about CSS.
  • Very interesting article by Adam Wathan, where he starts doubting the separation of structure and presentation. Money quote:

    My markup wasn't concerned with styling decisions, but my CSS was very concerned with my markup structure.

    There is some truth here, and I must admit I’ve started doubting the strict separation of structure, presentation, and behaviour we made popular in web development all those many years ago. I need some time to assimilate all of this, since I spent most of 2000-2004 telling web developers to strictly separate their concerns. Now ... maybe it’s time to revisit that.
    Food for thought.
  • A lengthy guide to using CSS custom properties, either in a Sass context or not. I especially like the heading “Don’t Be Too Clever.” You can do amazingly complex things with custom properties, but it’s not always a good idea. For instance, you can calculate font sizes and widths and such at runtime, but that might eat up too much valuable processor time. So calculate the values beforehand and let the browser switch between them.
  • Brad Frost on CSS architecture for design systems. He, too, inserts BEM into his solution, so I guess there must be something good there.
  • And while we’re on this topic, here’s Harry Roberts’s CSS guidelines. Not exactly new, but still important.
  • How browsers position floats. A technical breakdown of what happens when you float elements. With interactive example.
  • A breakdown of CSS !important and what we can use it for.
    Doesn’t really treat my favourite use case: figuring out if you have a cascade problem. If styles mysteriously don’t show up, I add !important. If they do show up now, I have a cascade problem. If they still don’t, something else is going on. Useful debugging information. Afterwards I remove the !important and fix my code.
  • Interesting breakdown of how Microsoft CEO Nadella shifted from a Windows Everywhere strategy to a Services, Not Devices strategy. It took him five years because in the short term Windows mattered a lot to Microsoft clients.

    [Office for iPad was] an easy win that symbolized the exact shift in mindset Microsoft needed: non-Windows platforms would be targets for Microsoft services, not competitors for Windows.

    True. Right now, what Microsoft could do to target non-Windows platforms is porting Edge to Android and creating a competitor for Google Services. Now that would be interesting. Still, it’s a huge investment and so far it doesn’t appear to be forthcoming.
  • We always assumed that smartphones would entirely replace feature phones in the long run. This report, however, finds that feature phone traffic is actually going up in India, where both iOS and Android lose market share. This share is picked up by the new FirefoxOS-based KaiOS feature phone system, which, according to this report, has already overtaken iOS in India.
    Interesting times are here again? In any case I badly need a Nokia 8110, which runs KaiOS.
  • GDRP and ads. According to this article, the new European GDPR (you know, the reason you got so many mails last week) is going to pop the adtech bubble. Doc Searls distinguishes between the ads themselves, which are not necessarily evil or bad, and adtech, which purports to connect the right ads to the right people, but mysteriously doesn’t and (my interpretation!) is so in awe of its own cleverness that it ignores the ad-blocker writing on the wall.
  • null >= 0 evaluates to true in JavaScript. Why? Abinav Seelan explains.
  • Brian Rinaldi argues against the job title “full-stack developer” by giving a lengthy list of things these developers are supposed to know. No one can be a specialist in all of these areas, and I’m not sure we need a lot of generalists who know a little bit about everything.
    So don’t call yourself a full-stack developer. You can’t be.
  • Dave Winer on why the Internet is going the wrong way.
  • Have a tip for the next Linkbait? Or a comment on this one? Let me know (or here or here).

Video: Mobile Planet

LukeW - Mon, 05/28/2018 - 2:00pm

For the past six years, I've presented a walkthrough of the latest mobile data and design insights and solutions I've been exploring at Google's Conversions event in Dublin. This year's video recording is now live.

This year's presentation is a data-informed big picture view of our mobile planet, how to design products for it, and why covering on-boarding, performance, touch gestures, and more.

All Annual Sessions:

Big thanks to the Conversions@Google team for making these sessions available to all.

Developing a design environment

Css Tricks - Mon, 05/28/2018 - 10:19am

Jules Forrest discusses some of the work that her team at Credit Karma has been up to when it comes to design systems. Jules writes:

...in most engineering organizations, you spend your whole first day setting up your development environment so you can actually ship code. It’s generally pretty tedious and no one likes doing it, but it’s this thing you do to contribute meaningful work to production. Which got me thinking, what would it look like to make it easier for designers to design for production?

That’s what Jules calls a “design environment” and she’s even written a whole bunch of documentation in Thread, Credit Karma’s design system, for designers on their team to get that design environment up and running. That’s stuff like fonts, Sketch plugins, and other useful assets:

These problems have certainly been tackled by other teams in the past but this is the first time I’ve heard the phrase “design environment” before and I sort of love the heck out of it. Oh, and this post reminds me of a piece by Jon Gold where he wrote about Painting with Code.

Direct Link to ArticlePermalink

The post Developing a design environment appeared first on CSS-Tricks.

Solving Life’s Problems with CSS

Css Tricks - Mon, 05/28/2018 - 5:33am

Or: When all you have is a CSS hammer, the world looks like a CSS nail.

Whenever I hear a perfectly nice comment like, "Yeah, representing the tech field!" in response to my pure-CSS art, I get a sharp feeling of panic.

Like many people who work on UIs for a living, I have difficulty applying the "tech" term to myself without feeling like a fraud. Impostor syndrome is a hard thing to shake. A front-end specialist? Oh, you mean the stuff that isn’t really code? That amps up the feeling from impostor to villain.

Even though 90% of my daily work revolves around JavaScript, I feel as if the "tech" label is a shiny trophy that I greedily snatched from someone more deserving. As if there are nameless, starving computer science grads out there and I’m stealing the ramen right out of their mouths.

Take for example this scenario that computer-science schooled people are probably familiar with:

CS Course Problem: Write a script that sorts then randomizes this dataset N times, but for every 8th Q print 12 trees stacks queues void flip flop and you don’t stop rockin’ till returning the sum of the results 4x + 3y.

My proposal: (12 hours and eight gallons of coffee later) Done! Here are 1,200 lines of beautifully formatted code! There are forty-three loops, thirty-two if/else conditions, and eighty-three lines of comments because I keep getting lost in the file — but I’ve achieved the exact desired result!

CS Course Answer: Use three lines of recursion.

My response: ...%#@& you.

An exaggeration, but it’s helpful to be regularly humbled like that. It helps you grow as a programmer, problem-solver, and human. Plus, it prepares you for real-world scenarios in your career where you will regularly come across interesting challenges that require a bit of creative thinking.

When it comes to the CSS side of things, no employer will ever ask you to produce a detailed painterly CSS art piece. If they do, you really should immediately report that as harassment to HR. But it is very common to have a small and sometimes unusual request. One that may not have an obvious solution right away.

The "tech-free" CSS — with its glaring lack of programming functions — may not immediately come to mind when given such a challenge. But make no mistake, it can be one of the most valuable tools in your algorithm arsenal! For example:

CSS Course Problem: A disclaimer message needs to pop up into view as a warning when a user clicks a certain input field.

Proposal: Piece of cake! We use our trusty friend JavaScript to trigger a click or focus event on the input element. Then we load the disclaimer template. Then we make an Ajax call for content. Once our Promise() is resolved, we append the element to the page and find where to insert it by way of finding the event.target’s parent element. After the disclaimer is loaded, we need to ensure that we’ve handled another click event on the actual disclaimer itself to toggle out of it. Once we’ve toggled out of it, we destroy the element. If the input is clicked again, we repeat this process.

CSS Course Solution: input:focus + .disclaimer { display: block; }

Response: ...%#@& off.

Again, it’s an exaggeration (and the world’s least efficient JavaScript solution), but it’s only a slight exaggeration. I see those types of proposals being put to use way more often than you’d expect. Being able to provide ridiculously quick solutions to what have long been thought of as lengthy JavaScript problems? That’s one of the ways in which CSS allows me to feel like a master of tech.

This is just one of the many things I love about CSS. The limited set of rules is exactly what makes it so fun. You don’t expect CSS to fulfill all of your needs, which is what makes it all the more rewarding when you end up finding a way that it can.

Now, say there’s a design challenge. You’re asked to implement this shape in the browser:

Proposal 1: "There’s no "reverse-border-radius" property to create that shape in CSS, so that’s not possible. Just embed an image. Duh."

Answer 1: Okay fine, don’t learn CSS for all I care.

No please come back! I want you to learn.

It's true that no one will penalize you for using an image. There are no CSS police enforcing this rule. Hell, there aren’t even any computer science police stopping you from using a terrible billion-line algorithm instead of a beautifully simple recursive one. But if there’s any concept to be shared between CSS and CS it’s that "not possible" is hardly ever the answer.

So let’s try a brute-force method, shall we?

Proposal 2: Start with a black rectangle, then notch out the sides with two border-radiused <div> elements that match the white background color, like so:

Answer 2: Alright! Now we’re getting somewhere. The shape is coming together. But what if the background is varying? Or a gradient? Or an image? How would that look?

Hm. No longer looks quite as nice. So how we do allow our natural background to shine through, while still keeping a sloping-inward shape — something that CSS isn’t natively built to support?

Proposal 3: Keep the rectangle. Keep the curved divs. But don’t fill the rectangle with color, and don’t fill the curved divs with color either. Instead, spread the black color outside of the curved divs, using box-shadow. The rectangle will simply need an overflow: hidden; to keep that box-shadow color contained within its boundaries.

Answer 3: Well done! Beautiful!

The above technique has been described in even better detail in Ana Tudor’s excellent post on scooped corners. And it’s an excellent concept to keep in mind when presented with “not possible with CSS” problems. It’s one that I love to use when creating art.

Take, for example, this portion of one of my CSS paintings:

The human neck unfortunately does not usually come conveniently packaged in a perfect rectangular shape. But HTML does, so that’s what we have to work with.

But wait, isn’t that neck-shape pretty similar to the curvy black shape that we outlined above?

Yep, it all started with a big rectangle. In this case, our outward-curving divs just used a softer blending on their box-shadow.

Outside of work, I keep coming back to CSS for artistic inspiration.

Because something about those limitations just calls to me. I know I’m not alone when I say that a rigid set of restrictions is the best catalyst for creativity. Total artistic freedom can be a paralyzing concept.

That can sometimes be the case with programming. If you have the most powerful programming languages in the world at your disposal, it starts to seem natural that you should then have no difficulty solving any programming problem. With all these amazing tools offering countless solutions to solve the same problem, it's no wonder that we sometimes freeze up with information overload.

Sure, CSS can be thought of as not being a “true” component of the tech stack. I would not even argue against that. Let's face it, pure CSS is not about recursion or data storage or database-querying. Its primary purpose is indeed for prettification — which doesn’t exactly help the stigma of front-enders not being “real” techies or programmers.

CSS never made any bold claims or promises. It has merely offered assistance, and it just turns out that its assistance can be downright heroic.

If you are a front-ender who has to deal with a bunch of DevOps folks mocking their CSS, just wait and see what the response is when you sneak a body { display: none; } onto production. We'll see who's laughing then!*

* They will still be the ones laughing because you will be fired. Please don't do this.

The post Solving Life’s Problems with CSS appeared first on CSS-Tricks.

Browser Extensions I Actually Use

Css Tricks - Sun, 05/27/2018 - 2:22am

I use around 10 at the moment and they all provide functionality to me I find extremely important. Sometimes that functionality is every day all day. Sometimes it's once in a blue moon but when you need it, you need it.

Direct Link to ArticlePermalink

The post Browser Extensions I Actually Use appeared first on CSS-Tricks.

Service Worker Cookbook

Css Tricks - Fri, 05/25/2018 - 10:54am

I stumbled upon this site the other day from Mozilla that’s a collection of recipes to get started with a Service Worker — from caching strategies and notifications to providing an offline fallback to your users, this little cookbook has it all.

You can also check out our guide to making a simple site work offline and the offline site that resulted from it.

Direct Link to ArticlePermalink

The post Service Worker Cookbook appeared first on CSS-Tricks.

Learning Gutenberg: Building Our Custom Card Block

Css Tricks - Fri, 05/25/2018 - 4:42am

We’ve got some base knowledge, we’ve played with some React and now we’ve got our project tools set up. Let’s dive into building our custom block.

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101
  6. Setting up a Custom webpack
  7. A Custom "Card" Block (This Post)
What we’re building

We’re going to build a custom card block that features an image, a title and a summary. It’s a really common design pattern in the web and it also let’s us look at some core Gutenberg components, along with core WordPress elements, such as the Media Library. We’ll also play with some display logic with JSX for the front-end markup.

Our glorious custom card block!

Our glorious custom card block!

We’re going to focus solely on the CMS aspect of this block in this tutorial. What it renders is some nice, clean markup on the front-end though. You could extend this block to feature front-end styles too, if you wanted.

Getting started

The first thing we’re going to do is open up the block.js file that we created in the previous section. In your active plugin folder, this is located at blocks/src/block/block.js.

If you are working from the file structure created with create-guten-block, you might want to start by deleting everything in block.js and writing your code from scratch along with the tutorial.

Right at the top of this file, add the following:

const { registerBlockType, RichText, MediaUpload, PlainText } = wp.blocks; const { Button } = wp.components;

We covered destructuring assignments in Part 3. This is a great example of those, which you’ll see a lot in Gutenberg code. Here, wp.components features more than Button, but that’s all we want, so that’s all we’ll get. It’s a neat because it prevents us from having to write stuff like wp.components.Button, which will be great for keeping our code nice and light.

We’ve got that cleared up, so let’s import our Sass files. This is so that webpack detects them.

import './style.scss'; import './editor.scss';

Now let’s start writing the component that powers our block. Right under those lines, add the following:

registerBlockType('card-block/main', { title: 'Card', icon: 'heart', category: 'common' });

This code tells Gutenberg, "Hey, I’ve got a block for you to add to your collection. It’s called 'Card,’ it has a 'heart' icon and it should live in the 'common' category." This is our component’s basic definition, so let’s add some more code.

This should look familiar—remember our challenge in Part 2, create-guten-block? In case you need reminding, check it out here. The first six of those were relatively straightforward and involved replacing strings or bit of HTML. The seventh item, “Make the paragraph text editable," is much more complicated to implement and was intended to get you thinking a bit. The time has come though, and we will indeed make some text editable in Gutenberg!

You may also recognize this registerBlockType function from the PHP register_block_type function we used in the last article. While that function registers a block from the server-side of WordPress, this one registers our block into the React ecosystem on the client side. Both are necessary to have a block that uses React, and their registered names, card-block/main must match.

Add the following code, but make sure you put a comma after 'common', so it looks like this: 'common',.

Here’s the code:

attributes: { title: { source: 'text', selector: '.card__title' }, body: { type: 'array', source: 'children', selector: '.card__body' }, imageAlt: { attribute: 'alt', selector: '.card__image' }, imageUrl: { attribute: 'src', selector: '.card__image' } }

Here, we are defining the editable attributes of our block and the DOM selector that they are assigned to. This attribute object works in a very similar way to the React state object. It even has a very similar updating method called setAttributes. We’ll get to that later though.

At this point, it’s worth a brief overview of state and attributes because they represent a whole new way of thinking for WordPress developers. I’ll take over for a moment to go over them. About Attributes and State

It may look like a simple JavaScript object, but that chunk of attributes introduces a whole swath of new concepts to a WordPress theme developer’s brain, not least of which is state. The concept of state has a long history in computer science, and life in general, really. Almost everything has a state. What state is your coffee cup in now? Empty, almost empty? How about your clothing? Are your shoes dirty or new? How about your body? Are you tired or wide awake?

At a high level, state simply refers to the present condition of a thing. In computer science, that thing is a computer program, and that program can be much, much simpler than what we create here on the web. Take a vending machine, for instance. The vending machine has a state that updates each time you put in a coin. When the state of the machine reaches a predefined amount, say $1.25, the machine knows to allow you to make your snack choice.

In Gutenberg, attributes track the present condition of data in a block. Attributes are the closest parallel we can draw to custom fields in Gutenberg, but they exist only in the context of Gutenberg and JavaScript. Let’s take the attribute above for title, for example:

title: { source: 'text', selector: 'card__title' },

When Gutenberg fires up, it says, “I need to find some text inside a selector called .card__title, and populate the value for title with whatever I find."

Attributes in Gutenberg are not directly connected to the database like custom fields are connected to post_meta. The entries source and selector are instructions for Gutenberg to populate the state of each block. When we load up the editor, it follows these instructions and assigns a value to title based on the markup saved in the database between the HTML comments that indicate a block of this type. We don’t see the value of title in the attributes we register, but if I were to access props.attributes.title, I would get whatever text exists in .card__title.

We’ve set up some basics, so let’s dive in to our edit function. This is what’s called when the block is accessed from the Gutenberg editor in visual mode. The user will see the rich interface, rather than the HTML code that it generates. That’s what I’ll cover next. Add our edit function

Let’s add some code in. Add the following after the closing } of the attributes object. Like before, make sure you add a trailing comma, so it looks like this },.

Add the following code after that:

edit({ attributes, className, setAttributes }) { return ( ); }

So, we’re using another destructuring assignment to selectively pick our passed parameters to the edit function. The two most important are attributes and setAttributes. The attributes parameter is the same as the attributes block, but it’s the current, reactive state. This means if the setAttributes function updates one of the attributes values, it will automatically update anywhere that references it, which is similar to our React component from Part 3.

There’s a big ol’ return in this function. Can you guess what’s going in it? Yup! We’re going to stick some JSX in there. Add the following within the return parentheses:

<div className="container"> <MediaUpload onSelect={ media => { setAttributes({ imageAlt: media.alt, imageUrl: media.url }); } } type="image" value={ attributes.imageID } render={ ({ open }) => getImageButton(open) } /> <PlainText onChange={ content => setAttributes({ title: content }) } value={ attributes.title } placeholder="Your card title" className="heading" /> <RichText onChange={ content => setAttributes({ body: content }) } value={ attributes.body } multiline="p" placeholder="Your card text" /> </div>

OK, there’s a lot going on in here, but it’s all stuff we’ve covered in previous parts of this series. What we’ve got here is a container with three existing Gutenberg components. For each, we are setting the relevant attribute as its value, a relevant placeholder and an onChange/onSelect handler. We’re also passing a custom renderer to the <MediaUpload />, which we’ll cover shortly.

Each onChange handler is a handy little expression that passes the new content that triggered the onChange into the setAttributes function, where we set which attributes object to update. This update then cascades into any reference of that attribute, where the content will update like magic. The <MediaUpload /> element features an onSelect event which is fired when the user selects or uploads an item to the media library.

Speaking of the <MediaUpload /> element, you’ll notice there’s a custom render attribute, which references a getImageButton function. Let’s write that next. Above the return in the edit function add the following:

const getImageButton = (openEvent) => { if(attributes.imageUrl) { return ( <img src={ attributes.imageUrl } onClick={ openEvent } className="image" /> ); } else { return ( <div className="button-container"> <Button onClick={ openEvent } className="button button-large" > Pick an image </Button> </div> ); } };

What this function does is detect if there’s an imageUrl in the attributes object. If there is, it’ll render that <img /> tag and let a user click it to select another. If there’s no image, it’ll render a WordPress <Button /> which prompts the user to pick an image. This calls the same openEvent that was passed into the function.

To keep things simple in this tutorial, we’ve bound a click to the <img /> element. You should consider building something fancy that leverages a <button /> for your production-ready blocks, for better accessibility support.

Right, that’s our edit function done. Not much code there, considering what it actually does, which is great!

Add our save function

We’ve got our Gutenberg editor-end of the block written now, which is the hard part. Now all we’ve got to do is tell Gutenberg what we want the block to do with the content. With the same reactive data from attributes, we can render out our front-end markup in real-time, too. That means when someone switches into HTML editing mode on the block, it’ll be up to date. If you edit it in HTML editing mode, the visual mode will also be kept up to date. Super useful.

Let’s dig in then. After our edit function, add a comma, so it looks like }, and then add the following on a new line:

save({ attributes }) { const cardImage = (src, alt) => { if(!src) return null; if(alt) { return ( <img className="card__image" src={ src } alt={ alt } /> ); } // No alt set, so let's hide it from screen readers return ( <img className="card__image" src={ src } alt="" aria-hidden="true" /> ); }; return ( <div className="card"> { cardImage(attributes.imageUrl, attributes.imageAlt) } <div className="card__content"> <h3 className="card__title">{ attributes.title }</h3> <div className="card__body"> { attributes.body } </div> </div> </div> ); }

Looks pretty similar to the edit function, right? Let’s step through it.

We start of by using a destructuring assignment to pull out the attributes from the passed paramaters, just like the previous edit function.

Then we have another image helper function that firstly detects if there’s an image and returns null if there’s not one. Remember: we return null in JSX if we want it to render nothing. The next thing this helper does is render a slightly varied <img /> tag if there’s alt text or not. For the latter, it hides it from a screen-reader by adding aria-hidden="true" and setting a blank alt attribute.

Lastly, our return spits out a nice .card block with clean, BEM-driven markup that will load on the front-end of our theme.

And that is that for our save function. We’re so close to having a completed block. Just one more step to go!

Add some style

OK, we’ve got this little bit to do and we’re done. The observant amongst you may have noticed some references to className dotted about. These are referencing our editor.scss rules, so let’s add them.

Open up editor.scss, which lives in the same directory as block.js. Add the following:

@import '../common'; .gutenberg { .container { border: 1px solid $gray; padding: 1rem; } .button-container { text-align: center; padding: 22% 0; background: $off-white; border: 1px solid $gray; border-radius: 2px; margin: 0 0 1.2rem 0; } .heading { font-size: 1.5rem; font-weight: 600; } .image { height: 15.7rem; width: 100%; object-fit: cover; } }

This is some loose CSS to give our block some card-like style. Notice it’s all nested within a .gutenberg class? This is to battle the specificity of some core styles. Within the editor, there is a <div class="gutenberg" wrapped around the block area of the post editor screen, so we can make sure to only affect those elements with this nesting. You’ll probably also notice that we’re importing another Sass file, so let’s fill that one.

Open common.scss which lives in the src directory, which is the parent of the current block directory that we’re in.

/* * Common SCSS can contain your common variables, helpers and mixins * that are shared between all of your blocks. */ // Colors $gray: #cccccc; $off-white: #f1f1f1;

Anyway, guess what? We’ve only gone and built out a custom card block!! Let’s give it a test-drive.

First, check your block is all-good. This is what the complete block.js file should look like:

const { registerBlockType, RichText, MediaUpload, PlainText } = wp.blocks; const { Button } = wp.components; // Import our CSS files import './style.scss'; import './editor.scss'; registerBlockType('card-block/main', { title: 'Card', icon: 'heart', category: 'common', attributes: { title: { source: 'text', selector: '.card__title' }, body: { type: 'array', source: 'children', selector: '.card__body' }, imageAlt: { attribute: 'alt', selector: '.card__image' }, imageUrl: { attribute: 'src', selector: '.card__image' } }, edit({ attributes, className, setAttributes }) { const getImageButton = (openEvent) => { if(attributes.imageUrl) { return ( <img src={ attributes.imageUrl } onClick={ openEvent } className="image" /> ); } else { return ( <div className="button-container"> <Button onClick={ openEvent } className="button button-large" > Pick an image </Button> </div> ); } }; return ( <div className="container"> <MediaUpload onSelect={ media => { setAttributes({ imageAlt: media.alt, imageUrl: media.url }); } } type="image" value={ attributes.imageID } render={ ({ open }) => getImageButton(open) } /> <PlainText onChange={ content => setAttributes({ title: content }) } value={ attributes.title } placeholder="Your card title" className="heading" /> <RichText onChange={ content => setAttributes({ body: content }) } value={ attributes.body } multiline="p" placeholder="Your card text" formattingControls={ ['bold', 'italic', 'underline'] } isSelected={ attributes.isSelected } /> </div> ); }, save({ attributes }) { const cardImage = (src, alt) => { if(!src) return null; if(alt) { return ( <img className="card__image" src={ src } alt={ alt } /> ); } // No alt set, so let's hide it from screen readers return ( <img className="card__image" src={ src } alt="" aria-hidden="true" /> ); }; return ( <div className="card"> { cardImage(attributes.imageUrl, attributes.imageAlt) } <div className="card__content"> <h3 className="card__title">{ attributes.title }</h3> <div className="card__body"> { attributes.body } </div> </div> </div> ); } });

If you’re happy, let’s fire up webpack. While in your current plugin directory in terminal, run this:

npx webpack --watch

This is slightly different to the previous part in the series because we’ve added the --watch argument. This basically keeps an eye on your js files and re-runs webpack if they change.

Fire up the editor!

Let’s fire up the Gutenberg editor by loading up a post in the WordPress back end. In the Gutenberg editor, click the little plus icon and look in the “blocks" tab and there it is: our awesome new card block!

Go ahead and give it a test drive and add some content in there. Feels good right?

Here’s a quick video of what you should be seeing right now, with your fancy new card block:

And with that, you’re done &#x1f389;

Here’s a thing you might be thinking: Aren’t blocks kind of a replacement for custom fields? Can’t I now create my own content structure directly within WordPress instead of using a plugin like Advanced Custom Fields? Not quite... Blocks vs. Custom Fields

While Gutenberg does afford us the ability to customize the structure of data entry from the user’s experience, on the back-end it’s no different than the current WYSIWYG editor. Data saved from a block is part of the post_content column in the wp_posts database table—it’s not stored separately in wp_postmeta like custom fields. This means that, at present, we cannot access the data from our card block from another post in the same way we could if we had created custom fields for title, image and content with a standard Advanced Custom Fields setup.

That said, I could see some really interesting plugins surfacing that provide a way to port data from a block to other parts of a website. With the WordPress REST API, the possibilities are just about limitless! In our screencast, Andy and I took a stab at incorporating an API request into our card block and, although things didn’t turn out exactly as planned, the tools are already in place and you can get a taste of what could be possible with Gutenberg in the future. Time will tell!

Wrapping up and next steps

What a journey we’ve been on together! Let’s list out what you’ve learned in this series:

So, where can you go from here? Now that you’ve got some solid base knowledge from this series, you could do some further learning. There’s already fantastic resources for that:

Some interesting case studies:

Keep an eye on these resources to stay up to date with the project:

Experimental things happening with Gutenberg:

Once Gutenberg becomes part of WordPress core in version 5.0 (release date TBD), you could also publish a useful custom block in the WordPress plugins directory. There’s definitely room for some handy components such as the card block that you’ve just built.

We hope you’ve enjoyed this series, because we’ve certainly enjoyed making it. We really hope this helps you get into Gutenberg and that you build some cool stuff. You should totally send us links of stuff you have built too!

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101
  6. Setting up a Custom webpack
  7. A Custom "Card" Block (This Post)

The post Learning Gutenberg: Building Our Custom Card Block appeared first on CSS-Tricks.

Learning Gutenberg: Setting up a Custom webpack Config

Css Tricks - Thu, 05/24/2018 - 4:22am

Gutenberg introduces the modern JavaScript stack into the WordPress ecosystem, which means some new tooling should be learned. Although tools like create-guten-block are incredibly useful, it’s also handy to know what’s going on under the hood.

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101
  6. Setting up a Custom webpack (This Post)
  7. A Custom "Card" Block
The files we will be configuring here should be familiar from what we covered in the Part 2 Primer with create-guten-block. If you’re like me (before reading Andy’s tutorial, that is!) and would rather not dive into the configuration part just yet, the scaffold created by create-guten-block matches what we are about to create here, so you can certainly use that as well.

Let’s jump in!

Getting started

Webpack takes the small, modular aspects of your front-end codebase and smooshes them down into one efficient file. It’s highly extendable and configurable and works as the beating heart of some of the most popular products and projects on the web. It’s very much a JavaScript tool, although it can be used for pretty much whatever you want. For this tutorial, it’s sole focus is JavaScript though.

What we’re going to get webpack doing is watch for our changes on some custom block files and compile them with Babel to generate JavaScript files that can be read by most browsers. It’ll also merge any dependencies that we import.

But first, we need a place to store our actual webpack setup and front-end files. In Part 2, when we poked around the files generated by create-guten-block, we saw that it created an infrastructure for a WordPress plugin that enqueued our front-end files in a WordPress way, and enabled us to activate the plugin through WordPress. I’m going to take this next section to walk us through setting up the infrastructure for a WordPress plugin for our custom block. Setting up a plugin

Hopefully you still have a local WordPress instance running from our primer in Part 2, but if not, you’ll need to have one installed to continue with what we’re about to do. In that install, navigate to wp-content/plugins and create a fresh directory called card-block (spoiler alert: we’re going to make a card block... who doesn’t like cards?).

Then, inside card-block, create a file called card-block.php. This will be the equivalent to plugin.php from create-guten-block. Next, drop in this chunk of comments to tell WordPress to acknowledge this directory as a plugin and display it in the Plugins page of the Dashboard:

<?php /* Plugin Name: Card Block */

Don’t forget the opening PHP tag, but you can leave the closing one off since we’ll be adding more to this file soon enough.

WordPress looks for these comments to register a plugin in the same way it looks for comments at the top of style.css in a theme. This is an abbreviated version of what you’ll find at the top of other plugins’ main files. If you were planning to release it on the WordPress plugin repository, you’d want to add a description and version number as well as license and author information.

Go ahead and activate the plugin through the WordPress Dashboard, and I’ll take the steering wheel back to take us through setting up our Webpack config! Getting started with webpack

The first thing we’re going to do is initialize npm. Run the following at the root of your plugin folder (wp-content/plugins/card-block):

npm init

This will ask you a few questions about your project and ultimately generate you a package.json file, which lists dependencies and stores core information about your project.

Next, let’s install webpack:

npm install webpack --save-dev

You might have noticed that we’re installing webpack locally to our project. This is a good practice to get into with crucial packages that are prone to large, breaking changes. It also means you and your team are all singing off the same song sheet.

Then run this:

npm install extract-text-webpack-plugin@next --save-dev

Then these Sass and CSS dependencies:

npm install node-sass sass-loader css-loader --save-dev

Now, NPX to allow us to use our local dependencies instead of any global ones:

npm install npx -g

Lastly, run this:

npm install webpack-cli --save-dev

That will install the webpack CLI for you.

Now that we have this installed, we should create our config file. Still in the root of your plugin, create a file called webpack.config.js and open that file so we can get coding.

With this webpack file, we’re going to be working with traditional ES5 code for maximum compatibility, because it runs with Node JS. You can use ES6 and Babel, but we’ll keep things as simple as possible for this tutorial.

Alight, let’s add some constants and imports. Add the following, right at the top of your webpack.config.js file:

var ExtractText = require('extract-text-webpack-plugin'); var debug = process.env.NODE_ENV !== 'production'; var webpack = require('webpack');

The debug var is declaring whether or not we’re in debug mode. This is our default mode, but it can be overridden by prepending our webpack commands with NODE_ENV=production. The debug boolean flag will determine whether webpack generates sourcemaps and minifies the code.

As you can see, we’re requiring some dependencies. We know that webpack is needed, so we’ll skip that. Let’s instead focus our attention on ExtractText. Essentially, ExtractText enables us to pull in files other than JavaScript into the mix. We’re going to need this for our Sass files. By default, webpack assumes everything is JavaScript, so ExtractText kind of *translates* the other types of files.

Let’s add some config now. Add the following after the webpack definition:

var extractEditorSCSS = new ExtractText({ filename: './blocks.editor.build.css' }); var extractBlockSCSS = new ExtractText({ filename: './blocks.style.build.css' });

What we’ve done there is instantiate two instances of ExtractText by passing a config object. All that we’ve set is the output of our two block stylesheets. We’ll come to these in the next series, but right now all you need to know is that this is the first step in getting our Sass compiling.

OK, after that last bit of code, add the following:

var plugins = [ extractEditorSCSS, extractBlockSCSS ];

Here we’ve got two arrays of plugins. Our ExtractText instances live in the core plugins set and we’ve got a couple of optimization plugins that are only smooshed into the core plugins set if we’re not in debug mode. We’re running that logic right at the end.

Next up, add this SCSS config object:

var scssConfig = { use: [ { loader: 'css-loader' }, { loader: 'sass-loader', options: { outputStyle: 'compressed' } } ] };

This object is going to tell our webpack instance how to behave when it comes across scss files. We’ve got it in a config object to keep things as DRY as possible.

Last up, the meat and taters of the config:

module.exports = { context: __dirname, devtool: debug ? 'inline-sourcemap' : null, mode: debug ? 'development' : 'production', entry: './blocks/src/blocks.js', output: { path: __dirname + '/blocks/dist/', filename: 'blocks.build.js' }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: [ { loader: 'babel-loader' } ] }, { test: /editor\.scss$/, exclude: /node_modules/, use: extractEditorSCSS.extract(scssConfig) }, { test: /style\.scss$/, exclude: /node_modules/, use: extractBlockSCSS.extract(scssConfig) } ] }, plugins: plugins };

That’s our entire config, so let’s break it down.

The script starts with module.exports which is essentially saying, "when you import or require me, this is what you’re getting." We can determine what we expose to whatever imports our code, which means we could run code above module.exports that do some heavy calculations, for example.

Next, let’s look at some of these following properties:

  • context is our base where paths will resolve from. We’ve passed __dirname, which is the current working directory.
  • devtool is where we define what sort of sourcemap we may or may not want. If we’re not in debug mode, we pass null with a ternary operator.
  • entry is where we tell webpack to start its journey of pack-ery. In our instance, this is the path to our blocks.js file.
  • output is what it says on the tin. We’re passing an object that defines the output path and the filename that we want to call it.

Next is module, which we’ll get into a touch more detail. The module section can contain multiple rules. In our instance, the only rule we have is looking for JavaScript and SCSS files. It’s doing this by searching with a regular expression that’s defined by the test property. The end-goal of the rule is to find the right sort of files and pass them into a loader, which is babel-loader in our case. As we learned in a previous tutorial in this series, Babel is what converts our modern ES6 code into more supported ES5 code.

Lastly is our plugins section. Here, we pass our array of plugin instances. In our project, we have plugins that minify code, remove duplicate code and one that reduces the length of commonly used IDs. This is all to make sure our production code is optimized.

For reference, this is how your full config file should look:

var ExtractText = require('extract-text-webpack-plugin'); var debug = process.env.NODE_ENV !== 'production'; var webpack = require('webpack'); var extractEditorSCSS = new ExtractText({ filename: './blocks.editor.build.css' }); var extractBlockSCSS = new ExtractText({ filename: './blocks.style.build.css' }); var plugins = [extractEditorSCSS, extractBlockSCSS]; var scssConfig = { use: [ { loader: 'css-loader' }, { loader: 'sass-loader', options: { outputStyle: 'compressed' } } ] }; module.exports = { context: __dirname, devtool: debug ? 'inline-sourcemap' : null, mode: debug ? 'development' : 'production', entry: './blocks/src/blocks.js', output: { path: __dirname + '/blocks/dist/', filename: 'blocks.build.js' }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: [ { loader: 'babel-loader' } ] }, { test: /editor\.scss$/, exclude: /node_modules/, use: extractEditorSCSS.extract(scssConfig) }, { test: /style\.scss$/, exclude: /node_modules/, use: extractBlockSCSS.extract(scssConfig) } ] }, plugins: plugins }; That’s webpack configured. I’ll take the mic back to show us how to officially register our block with WordPress. This should feel pretty familiar to those of you who are used to wrangling with actions and filters in WordPress. Registering our block

Back in card-block.php, our main task now is to enqueue the JavaScript and CSS files we will be building with webpack. In a theme, we would do this with call wp_enqueue_script and wp_enqueue_style inside an action added to wp_enqueue_scripts. We essentially do the same thing here, except instead we enqueue the scripts and styles with a function specific to blocks.

Drop this code below the opening comment in card-block.php:

function my_register_gutenberg_card_block() { // Register our block script with WordPress wp_register_script( 'gutenberg-card-block', plugins_url('/blocks/dist/blocks.build.js', __FILE__), array('wp-blocks', 'wp-element') ); // Register our block's base CSS wp_register_style( 'gutenberg-card-block-style', plugins_url( '/blocks/dist/blocks.style.build.css', __FILE__ ), array( 'wp-blocks' ) ); // Register our block's editor-specific CSS wp_register_style( 'gutenberg-card-block-edit-style', plugins_url('/blocks/dist/blocks.editor.build.css', __FILE__), array( 'wp-edit-blocks' ) ); // Enqueue the script in the editor register_block_type('card-block/main', array( 'editor_script' => 'gutenberg-card-block', 'editor_style' => 'gutenberg-card-block-edit-style', 'style' => 'gutenberg-card-block-edit-style' )); } add_action('init', 'my_register_gutenberg_card_block');

As the above comments indicate, we first register our script with WordPress using the handle gutenberg-card-block with two dependencies: wp-blocks and wp-elements. This function only registers a script, it does not enqueue it. We do something similar for out edit and main stylesheets.

Our final function, register_block_type, does the enqueuing for us. It also gives the block a name, card-block/main, which identifies this block as the main block within the namespace card-block, then identifies the script and styles we just registered as the main editor script, editor stylesheet, and primary stylesheet for the block.

If you are familiar with theme development, you’ve probably used get_template_directory() to handle file paths in hooks like the ones above. For plugin development, we use the function plugins_url() which does pretty much the same thing, except instead of concatenating a path like this: get_template_directory() . 'https://cdn.css-tricks.com/script.js', plugins_url() accepts a string path as a parameter and does the concatenation for us. The second parameter, _ FILE _, is one of PHP’s magic constants that equates to the full file path of the current file.

Finally, if you want to add more blocks to this plugin, you’d need a version of this function for each block. You could work out what’s variable and generate some sort of loop to keep it nice and DRY, further down the line. Now, I’ll walk us through getting Babel up and running. Getting Babel running

Babel turns our ES6 code into better-supported ES5 code, so we need to install some dependencies. In the root of your plugin (wp-content/plugins/card-block), run the following:

npm install babel-core babel-loader babel-plugin-add-module-exports babel-plugin-transform-react-jsx babel-preset-env --save-dev

That big ol’ npm install adds all the Babel dependencies. Now we can add our .babelrc file which stores some settings for us. It prevents us from having to repeat them over and over in the command line.

While still in your theme folder, add the following file: .babelrc.

Now open it up and paste the following:

{ "presets": ["env"], "plugins": [ ["transform-react-jsx", { "pragma": "wp.element.createElement" }] ] }

So, what we’ve got there are two things:

"presets": ["env"] is basically magic. It automatically determines which ES features to use to generate your ES5 code. We used to have to add different presets for all the different ES versions (e.g. ES2015), but it’s been simplified.

In the plugins, you’ll notice that there’s a React JSX transformer. That’s sorting out our JSX and turning it into proper JavaScript, but what we’re doing is telling it to generate WordPress elements, rather than React elements, which JSX is more commonly associated with.

Generate stub files

The last thing we’re going to do is generate some stub files and test that our webpack and WordPress setup is all good.

Go into your plugin directory and create a folder called blocks and, within that, create two folders: one called src and one called dist.

Inside the src folder, create the following files. We’ve added the paths, too, so you put them in the right place:

  • blocks.js
  • common.scss
  • block/block.js
  • block/editor.scss
  • block/style.scss

Now that you've created those files, open up blocks.js and add this one-liner and save:

import './block/block';

OK, so now we’ve generated the minimum amount of things, let’s run webpack. Open up your terminal and move into your current plugin folder—then we can run the following, which will fire-up webpack:

npx webpack

Pretty dang straightforward, huh? If you go ahead and look in your dist folder, you should see some compiled goodies in there!

Wrapping up

A lot of setup has been done, but all of our ducks are in a row. We’ve set up webpack, Babel and WordPress to all work as a team to build out or custom Gutenberg block (and future blocks). Hopefully now you feel more comfortable working with webpack and feel like you could dive in and make customizations to fit your projects.

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101
  6. Setting up a Custom webpack (This Post)
  7. A Custom "Card" Block

The post Learning Gutenberg: Setting up a Custom webpack Config appeared first on CSS-Tricks.

?High Performance Hosting with No Billing Surprises

Css Tricks - Thu, 05/24/2018 - 4:13am

(This is a sponsored post.)

With DigitalOcean, you can spin up Droplet cloud servers with industry-leading price-performance and predictable costs. Our flexible configurations are sized for any application, and we save you up to 55% when compared to other cloud providers.

Get started today. Receive a free $100/60-day account credit good towards any DigitalOcean services.

Direct Link to ArticlePermalink

The post ?High Performance Hosting with No Billing Surprises appeared first on CSS-Tricks.

9 Rules For UX Design

Usability Geek - Wed, 05/23/2018 - 11:19am
Websites designed with user experience (UX) in mind have much better chances of establishing loyal users and improving conversion rates. In fact, the importance of connecting with users and building...
Categories: Web Standards

Learning Gutenberg: React 101

Css Tricks - Wed, 05/23/2018 - 9:41am

Although Gutenberg is put together with React, the code we’re writing to make custom blocks isn’t. It certainly resembles a React component though, so I think it’s useful to have a little play to get familiar with this sort of approach. There’s been a lot of reading in this series so far, so let’s roll-up our sleeves and make something cool.

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101 (This Post)
  6. Setting up a Custom webpack
  7. A Custom "Card" Block
Let’s make an “About Me” component

We’re going to make a single React component that updates the background color of a page and the intro text based on data you input into a couple of fields. “I thought this was supposed to be cool,” I hear you all mutter. I’ll admit, I may have oversold it, but we’re going to learn some core concepts of state-driven JavaScript which will come in handy when we dig into our Gutenberg block.

For reference, this is what we’re going to end up with:

Getting started

The first thing we’re going to do is fire up CodePen. CodePen can be used for free, so go head over there and create a new Pen.

Next, we’re going to pull in some JavaScript dependencies. There are three editor screens—find the JS screen and click the settings cog. This will open up a Pen Settings modal where you’ll find the section titled Add External Scripts/Pens. Right at the bottom, theres a Quick-add select menu. Go ahead and open that up.

From the menu, select React. Once that’s selected, open the menu and select ReactDOM. You’ll see that this has pre-filled some text boxes.

Lastly, we need to enable our ES6 code, so at the menu titled JavaScript Preprocessor, select Babel.

Now, go ahead and click the big Save & Close button.

What we’ve done there is pull the main React JS library and ReactDOM library. These will enable us to dive in and write our code, which is our next step.

Setup our CSS

Let’s make it look cool. First up though, let’s setup our CSS editor. The first thing we’re going to do is set it up to compile Sass for us. Just like we did with the JS editor, click on the settings cog which will bring up the Pen Settings modal again—this time with the CSS settings.

At the top, there’s a CSS Preprocessor menu. Go ahead and select SCSS from there.

When that’s done, go down to the Add External Stylesheets/Pens and paste the following three links into separate text-boxes:

https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.css https://fonts.googleapis.com/css?family=Work+Sans:300 https://rawgit.com/hankchizljaw/boilerform/master/dist/css/boilerform.min.css

Those three in order give us a reset, a fancy font and some helpful form styles.

Now that they’re all set, go ahead and click the "Save & Close" button again.

Adding a bit of style

We’re all setup so this step should be easy. Paste the following Sass into the CSS editor:

:root { --text-color: #f3f3f3; } * { box-sizing: border-box; } html { height: 100%; font-size: 16px; } body { height: 100%; position: relative; font-size: 1rem; line-height: 1.4; font-family: "Work Sans", sans-serif; font-weight: 300; background: #f3f3f3; color: #232323; } .about { width: 100%; height: 100%; position: absolute; top: 0; left: 0; color: var(--text-color); transition: all 2000ms ease-in-out; &__inner { display: flex; flex-direction: column; height: 100%; margin: 0 auto; padding: 1.2rem; } &__content { display: flex; flex-direction: column; justify-content: center; align-items: center; flex: 1 1 auto; font-size: 3rem; line-height: 1.2; > * { max-width: 30ch; } } &__form { display: flex; flex-direction: column; align-items: center; padding: 2rem 0; width: 100%; max-width: 60rem; margin: 0 auto; @media(min-width: 32rem) { flex-direction: row; justify-content: space-between; padding: 2rem; } > * { width: 15rem; } > * + * { margin: 1rem 0 0 0; @media(min-width: 32rem) { margin: 0; } } label { display: block; } } } // Boilerform overrides .c-select-field { &, &__menu { width: 100%; } } .c-input-field { width: 100%; } .c-label { color: var(--text-color); }

That’s a big ol’ chunk of CSS, and it’ll look like nothing has really happened, but it’s all good—we’re not going to have to worry about CSS for the rest of this section.

Digging into React

The first thing we’re going to do is give React something to latch on to. Paste this into the HTML editor of your Pen:

<div id="root"></div>

That’s it for HTML—you can go ahead and maximize your JS editor so we’ve got complete focus.

Let’s start our component code, by creating a new instance of a React component by writing the following JavaScript:

class AboutMe extends React.Component { }

What that code is doing is creating a new AboutMe component and extending React’s Component class, which gives us a load of code and tooling for free.

Right, so we’ve got a class, and now we need to construct it! Add the following code, inside the brackets:

constructor(props) { super(props); let self = this; };

We’ve got a few things going on here, so I’ll explain each:

constructor is the method that’s called when you write new AboutMe(), or if you write <AboutMe /> in your JSX. This constructs the object. The props parameter is something you’ll see a lot in React. This is the collection of properties that are passed into the component. For example: if you wrote <AboutMe name="Andy" />, you’d be able to access it in your constructor with props.name.

super is how we tell the class that we’ve extended to construct with its own constructor. You’ll see we’re also passing the props up to it in case any parent components need to access them.

Finally let self = this is a way of controlling the scope of this. Remember, because we’re using let, self will only be available in the constructor function.

Quick note for those readers not-so-confident in JavaScript: I found a deeper look at scope in JavaScript to result in a lot of “aha” moments in my learning. I highly recommend Kyle Simpson’s You Don’t Know JS book series (available for free on GitHub!). Volumes of note: this and Object Prototypes and Scope & Closures. Good stuff, I promise.

Now we’ve covered the constructor, let’s add some more code to it. After the let self = this; line, paste the following code:

self.availableColors = [ { "name": "Red", "value": "#ca3814" }, { "name": "Blue", "value": "#0086cc" }, { "name": "Green", "value": "#3aa22b" } ];

What we’ve got there is an array of objects that define our options for picking your favorite color. Go ahead and add your own if it’s not already there!

Your class definition and constructor should now look like this:

class AboutMe extends React.Component { constructor(props) { super(props); let self = this; // Set a list of available colors that render in the select menu self.availableColors = [ { "name": "Red", "value": "#ca3814" }, { "name": "Blue", "value": "#0086cc" }, { "name": "Green", "value": "#3aa22b" } ]; }; }

Pretty straightforward so far, right? Let’s move on and set some initial values to our reactive state. Add the following after the closing of self.availableColors:

// Set our initial reactive state values self.state = { name: 'Foo', color: self.availableColors[0].value };

This initial setting of state enables our component to render both a name and a color on load, which prevents it from looking broken.

Next, we’ll add our render function. This is a pure function, which does nothing but render the component based on the initial state or any state changes during the component’s lifecycle. You may have guessed already, but this is where the main body of our JSX lives.

Wait up! What’s a pure function? Welcome to functional programming, a hot topic in the React world. Pure functions are functions where, for input X, the output will always be Y. In an "impure" function, input X might result in different outputs, depending other parts of the program. Here’s a CodePen comparing pure and impure functions. Check out this article out, too, for more details.

Now, because there’s quite a lot of markup in this single component, we’re going to copy the whole lot into our function. Add the following under your constructor:

render() { let self = this; return ( <main className="about" style={ { background: self.state.color } }> <section className="about__inner"> <article className="about__content"> { self.state.name ? <p>Hello there. My name is { self.state.name }, and my favourite color is { self.getActiveColorName() }</p> : null } </article> <form className="[ about__form ] [ boilerform ]"> <div> <label className="c-label" htmlFor="name_field">Your name</label> <input className="c-input-field" type="text" id="name_field" value={ self.state.name } onChange={ self.updateName.bind(self) } /> </div> <div> <label className="c-label" htmlFor="color_field">Your favourite color</label> <div className="c-select-field"> <select className="c-select-field__menu" value={ self.state.color } onChange={ self.updateColor.bind(self) } id="color_field"> { self.availableColors.map((color, index) => { return ( <option key={ index } value={ color.value }>{ color.name }</option> ); })} </select> <span className="c-select-field__decor" aria-hidden="true" role="presentation">?</span> </div> </div> </form> </section> </main> ); };

You may be thinking something like: “Holy cow, there’s a lot going on here.” Let’s dissect it, so don’t worry about copying code for a bit—I’ll let you know where we’re going to do that again. Let’s just focus on some key bits for now.

In JSX, you need to return a single element, which can have child elements. Because all of our code is wrapped in a <main> tag, we’re all good there. On that <main> tag, you’ll see we have an expression in an attribute, like we covered in Part 2. This expression sets the background color as the current active color that’s set in our state. This will update like magic when a user changes their color choice without us having to write another line of code for it in this render function. Pretty cool, huh?

Inside the <article class="about__content"> element, you’ll notice this:

{ self.state.name ? <p>Hello there. My name is { self.state.name }, and my favourite color is { self.getActiveColorName() }</p> : null }

This ternary operator checks to see if there’s a name set and renders either a sentence containing the name or null. Returning null in JSX is how you tell it to render nothing to the client. Also related to this snippet: we were able to run this ternary operator within our JSX because we created an expression by opening some brackets. It’s a really useful way of sprinkling small, simple bits of display logic within your render function.

Next up, let’s look at an event binding:

<input className="c-input-field" type="text" id="name_field" value={ self.state.name } onChange={ self.updateName.bind(self) } />

If you don’t bind an event to your input field, it’ll be read only. Don’t panic about forgetting though. React helpfully warns you in your console.

Remember, self is equal to this, so what we’re doing is attaching the updateName function to the input’s onChange event, but we’re also binding self, so that when we’re within the updateName function, this will equal AboutMe, which is our component.

The last thing we’re going to look at in the render function is loops. Here’s the snippet that renders the color menu:

<select className="c-select-field__menu" value={ self.state.color } onChange={ self.updateColor.bind(self) } id="color_field"> { self.availableColors.map((color, index) => { return ( <option key={ index } value={ color.value }>{ color.name }</option> ); }) } </select>

The value and change setup is the same as the above <input /> element, so we’ll ignore them and dive straight in to the loop. What we’ve done is open up an expression where we run a pretty standard Array Map function, but, importantly, it returns JSX in each iteration, which allows each option to render with the rest of the JSX.

Wiring it all up

Now that we’ve got our core aspects of the component running, we need to wire it up. You’ll notice that your CodePen isn’t doing anything at the moment. That’s because of two things:

  • We haven’t attached the component to the DOM yet
  • We haven’t written any methods to make it interactive

Let’s start with the former and add our change event handlers. Add the following underneath your constructor function:

updateName(evt) { let self = this; self.setState({ name: evt.target.value }) }; updateColor(evt) { let self = this; self.setState({ color: evt.target.value }) };

These two functions handle the onChange events of the <select> and <input> and set their values in state using React’s setState function. Now that the values are in state, anything that is subscribed to them will update automatically. This means that the ternary statement that renders your name and the background color will change in realtime as you type/select. Awesome. right?

Now, it would be recommended to make your code more DRY by combining these two as one change event handler that updates the relevant state. For this series though, let’s keep things simple and more understandable. &#x1f600;

Next up, let’s add the last method to our component. Add the following under your recently added update methods:

// Return active color name from available colors, based on state value getActiveColorName() { let self = this; return self.availableColors.filter(color => color.value === self.state.color)[0].name; };

This function uses one of my favorite JavaScript array methods: filter. With ES6, we can cherry pick array items based on their object value in one line, which is powerful stuff. With that power, we can pick the currently active availableColors item’s human-readable name and return it back.

JavaScript array methods are very cool and commonly spotted in the React ecosystem. Sarah Drasner made a seriously amazing “Array Explorer”—check it out here! Attaching the component to the DOM

The last thing we’re going to do is attach our component to the DOM, using ReactDOM. What we’re doing is saying, “Hey browser, fetch me the <div id="root"> element and render this React component in it.” ReactDOM is doing all the magic that makes that possible.

ReactDOM is a really smart package that takes changes in your dynamic React components, calculates what needs to be changed in the DOM and applies those changes in the most efficient possible way. With ReactDOM’s renderToString() method, you can also render your React components to a static string, which can then be inserted to your page with your server-side code. What’s smart about this is that references are added so that if your front-end picks up some server-rendered React, it’ll work out which components are needed and make the whole chunk of static markup dynamic automatically. Pretty damn smart, huh?

Anyway, back to our Pen. Add this right at the bottom of your JS editor:

// Attach our component to the <div id="root"> element ReactDOM.render(<AboutMe />, document.getElementById('root'));

Now, you’ll notice that your preview window has suddenly come alive! Congratulations — you just wrote a React component &#x1f389;

See the Pen About Me React Component by Andy Bell (@hankchizlja) on CodePen.

Wrapping up

In this part, you’ve learned about reactive, component JavaScript by writing a React component. This is relevant to your learning because custom Gutenberg blocks follow a very similar setup to a React component. Now that you’ve got a better understanding of how a React component works, you should be able to understand how a custom Gutenberg block works too.

It took me a bit to wrap my mind around the fact that, in terms of Gutenberg, React is only relevant to building blocks within the admin. In Gutenberg, React functions as a means of preparing the markup to be saved to the database in the post_content column. Using React on the front-end of a WordPress site to build something like this would be separate from what we will be doing in this series.

Next up in this series, we’re going to edit our WordPress theme so that we can build our custom Gutenberg block.

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101 (This Post)
  6. Setting up a Custom webpack
  7. A Custom "Card" Block

The post Learning Gutenberg: React 101 appeared first on CSS-Tricks.

Learning Gutenberg: Modern JavaScript Syntax

Css Tricks - Wed, 05/23/2018 - 4:03am

One of the key changes that Gutenberg brings to the WordPress ecosystem is a heavy reliance on JavaScript. Helpfully, the WordPress team have really pushed their JavaScript framework into the present and future by leveraging the modern JavaScript stack, which is commonly referred to as ES6 in the community. It’s how we’ll refer to it as in this series too, to avoid confusion.

Let’s dig into this ES6 world a bit, as it’s ultimately going to help us understand how to structure and build a custom Gutenberg block.

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax (This Post)
  5. React 101
  6. Setting up a Custom webpack
  7. A Custom "Card" Block
What is ES6?

ES6 is short for “EcmaScript 6” which is the 6th edition of EcmaScript. It’s official name is ES2015, which you may have also seen around. EcmaScript has since gone through many iterations, but modern JavaScript is still often referred to as ES6. As you probably guessed, the iterations have continued ES2016, ES2017 and so-on. I actually asked a question on ShopTalk show about what we could name modern JavaScript, which I the conclusion was... ES6.

I’m going to run through some key features of ES6 that are useful in the context of Gutenberg.

Functions

Functions get a heck of an update with ES6. Two changes I want to focus on are Arrow Functions and Class Methods.

Inside a class you don’t actually need to write the word function anymore in ES6. This can be confusing, so check out this example:

class Foo { // This is your 'bar' function bar() { return 'hello'; } }

You’d invoke bar() like this:

const fooInstance = new Foo(); const hi = fooInstance.bar();

This is commonplace in the land of modern JavaScript, so it’s good to clear it up.

Fun fact! ES6 Classes in JavaScript aren’t really “classes” in an object-oriented programming sense—under the hood, it’s the same old prototypical inheritance JavaScript has always had. Prior to ES6, the bar() method would be defined like so: Foo.prototype.bar = function() { ... }. React makes great use of ES6 classes, but it’s worth noting that ES6 classes are essentially syntactic sugar and hotly contested by some. If you’re interested in more details, checkout the MDN docs and this article on 2ality.

Right, let’s move on to arrow functions. &#x1f680;

An arrow function gives us a compact syntax that is often used as a one-liner for expressions. It’s also used to maintain the value of this, as an arrow function won’t rebind this like setInterval or an event handler would usually do.

An example of an arrow function as an expression is as follows:

// Define an array of fruit objects const fruit = [ { name: 'Apple', color: 'red' }, { name: 'Banana', color: 'yellow' }, { name: 'Pear', color: 'green' } ]; // Select only red fruit from that collection const redFruit = fruit.filter(fruitItem => fruitItem.color === 'red'); // Output should be something like Object { name: "Apple", color: "red" } console.log(redFruit[0]);

As you can see above, because there was a single parameter and the function was being used as an expression, we can redact the brackets and parenthesis. This allows us to really compact our code and improve readability.

Let’s take a look at how we can use an arrow function as an event handler in our Foo class from before:

class Foo { // This is your 'bar' function bar() { let buttonInstance = document.querySelector('button'); buttonInstance.addEventListener('click', evt => { console.log(this); }); } } // Run the handler const fooInstance = new Foo(); fooInstance.bar();

When the button is clicked, the output should be Foo { }, because this is the instance of Foo. If we were to replace that example with the following:

class Foo { // This is your 'bar' function bar() { let buttonInstance = document.querySelector('button'); buttonInstance.addEventListener('click', function(evt) { console.log(this); }); } } // Run the handler const fooInstance = new Foo(); fooInstance.bar();

When the button is clicked, the output would be <button> because the function has bound this to be the <button> that was clicked.

You can read more about arrow functions with Wes Bos, who wrote an excellent article about them.

const, let, and var

You may have noticed that I’ve been using const and let in the above examples. These are also a part of ES6 and I’ll quickly explain what each one does.

If a value is absolutely constant and won’t change through re-assignment, or be re-declared, use a const. This would commonly be used when importing something or declaring non-changing properties such as a collection of DOM elements.

If you have a variable that you want to only be accessible in the block it was defined in, then use a let. This can be confusing to understand, so check out this little example:

function foo() { if (1 < 2) { let bar = 'always true'; // Outputs: 'always true' console.log(bar); } // Outputs 'ReferenceError: bar is not defined' console.log(bar); } // Run the function so we can see our logs foo();

This is a great way to keep control of your variables and make them disposable, in a sense.

Lastly, var is the same old friend we know and love so well. Unfortunately, between const and let, our friend is becoming more and more redundant as time goes on. Using var is totally acceptable though, so don’t be disheartened—you just won’t see it much in the rest of this tutorial!

Destructuring assignment

Destructuring allows you to extract object keys at the point where you assign them to your local variable. So, say you’ve got this object:

const foo = { people: [ { name: 'Bar', age: 30 }, { name: 'Baz', age: 28 } ], anotherKey: 'some stuff', heyAFunction() { return 'Watermelons are really refreshing in the summer' } };

Traditionally, you’d extract people with foo.people. With destructuring, you can do this:

let { people } = foo;

That pulls the people array out of the the foo object, so we can dump the foo. prefix and use it as it is: people. It also means that anotherKey and heyAFunction are ignored, because we don’t need them right now. This is great when you’re working with big complex objects where being able to selectively pick stuff out is really useful.

You can also make use of destructuring to break up an object into local variables to increase code readability. Let’s update the above snippet:

let { people } = foo; let { heyAFunction } = foo;

Now we’ve got those two separate elements from the same object, while still ignoring anotherKey. If you ran console.log(people), it’d show itself an array and if you ran console.log(heyAFunction), you guessed it, it’d show itself as a function.

JSX

Most commonly found in React JS contexts: JSX is an XML-like extension to JavaScript that is designed to be compiled by preprocessors into normal JavaScript code. Essentially, it enables us to write HTML(ish) code within JavaScript, as long as we’re preprocessing it. It’s usually associated with a framework like React JS, but it’s also used for Gutenberg block development.

Let’s kick off with an example:

const hello = <h1 className="heading">Hello, Pal</h1>;

Pretty cool, huh? No templating system or escaping or concatenating required. As long as you return a single element, which can have many children, you’re all good. So let’s show something a touch more complex, with a React render function:

class MyComponent extends React.Component { /* Other parts redacted for brevity */ render() { return ( <article> <h2 className="heading">{ this.props.heading }</h2> <p className="lead">{ this.props.summary }</p> </article> ); } };

You can see above that we can drop expressions in wherever we want. This is also the case with element attributes, so we can have something like this:

<h2 className={ this.props.headingClass }> { this.props.heading } </h2>

You might be thinking, “What are these random braces doing?”

The answer is that this is an expression, which you will see a ton of in JSX. Essentially, it’s a little inline execution of JavaScript that behaves very much like a PHP echo does.

You’ll also probably notice that it says className instead of class. Although it looks like HTML/XML, it’s still JavaScript, so reserved words naturally are avoided. Attributes are camel-cased too, so keep and eye out for that. Here’s a useful answer to why it’s like this.

JSX is really powerful as you’ll see while this series progresses. It’s a great tool in our stack and really useful to understand in general.

I like to think of JSX as made up-tag names that are actually just function calls. Pick out any of the made-up tags you see in Gutenberg, let's use <InspectorControls /> for example, and do a "Find in Folder" for class InspectorControls and you’ll see something structured like Andy’s example here! If you don't find it, then the JSX must be registered as functional component, and should turn up by searching for function InspectorControls. Wrapping up

We’ve had a quick run through some of the useful features of ES6. There’s a ton more to learn, but I wanted to focus your attention on the stuff we’ll be using in this tutorial series. I’d strongly recommend your further your learning with Wes Bos’ courses, JavaScript 30 and ES6.io.

Next up, we’re going to build a mini React component!

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax (This Post)
  5. React 101
  6. Setting up a Custom webpack
  7. A Custom "Card" Block

The post Learning Gutenberg: Modern JavaScript Syntax appeared first on CSS-Tricks.

Just a Couple’a Fun Typography Links

Css Tricks - Tue, 05/22/2018 - 10:10am

The post Just a Couple’a Fun Typography Links appeared first on CSS-Tricks.

Learning Gutenberg: A Primer with create-guten-block

Css Tricks - Tue, 05/22/2018 - 4:01am

Welcome back! We’ve just taken a look at what Gutenberg is and how it operates from the admin side. Gutenberg is certainly going to have a massive impact on the WordPress world. If you are just arriving here and have no idea what we’re talking about, I recommend at least skimming Part 1 to make sure you have the appropriate background.

Let’s create a custom block with a bit of help from a wonderful tool called create-guten-block. Onward!

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block (This Post)
  4. Modern JavaScript Syntax
  5. React 101
  6. Setting up a Custom webpack
  7. A Custom "Card" Block
Blocks live in plugins

To create a Gutenberg block, you create a WordPress plugin. Anything that affects *content*, like a Gutenberg block certain will, needs to be a plugin so that it remains active even as you change themes. Something that is very theme-specific or just affects how your site looks can be part of the theme files or functions.php file in your theme. Read more about this distinction in our article about WordPress Functionality Plugins.

That said, the blocks in themes issue is a hot topic. The WordPress Theme Review Team is discussing whether or not to allow blocks in themes at all as part of themes. A post, “Getting Ready for Gutenberg”, on the Theme Review Team’s Make page posed this question, and was met with strong opinions from both sides. The general consensus, however, is that blocks are plugin territory.

WordPress.org is comprised of various teams, each with their own homepage at make.wordpress.org/team-name, channel in the WordPress Slack, and a weekly meeting. If you are interested in getting involved in WordPress or curious about how it operates, I highly recommend browsing through a list of the teams here, joining a Slack channel, and popping into a weekly meeting to see how it all happens.

In the far future, it’s possible that themes will consist of *just a stylesheet*, while all custom functionality and content structure come from blocks in plugins. I'm paraphrasing the words of Tammie Lister, Gutenberg's design lead, on this episode of Shoptalk Show. Very much worth a listen!

Taking a setup shortcut... for now

What’s kept me from diving head first into modern JavaScript is the dang configuration. The transpiling, the bundling, the code splitting, the tree shaking... yeesh, I’m busy! I love learning new things, but there’s a limit to my patience and, apparently, configuring a build process for a small test project is my limit.

It’s this sentiment that led to the development of a tool called create-react-app, zero-configuration build setup for, you guessed it, creating React apps. It’s brilliant. Assuming you have a functioning node and npm installation, you can run a single command and you have a project ready for you to start coding in React. The transpiling, bundling, and tree shaking is set up for you.

But wait... can we use create-react-app for Gutenberg blocks? No, but the aforementioned create-guten-block, developed and beautifully documented by Ahmad Awais, does pretty much the same thing for us! That’s what we’ll be using for our block.

create-guten-block is not the only block generating tool at our disposal! You can scaffold a block using WP-CLI, but I have chosen not to because the default setup is for ES5 (for now) and does not give us what we need for our journey into modern JavaScript. That being said, I found it helpful to dig through the ES5 implementation of a block as a way to reinforce the core concepts, so maybe give it a go after you finish here!

Yes, this is a shortcut. We are choosing to avoid understanding the core concepts of a technology by using a tool. We’ll have to learn these concepts someday. But for now, I’m totally fine bypassing this configuration step. My philosophy about using tools such as this: use them, but do so with the understanding that it *probably* won't save you time or effort in the long run.

It's worth noting that, like create-react-app, create-guten-block allows you to npm eject your configuration. This means exposing all of the settings the tool has created for us and making them available for customization. Note, however, that this is irreversible; if you eject and then make a mistake, you’re on your own to fix it! Like I said, you'll have to learn it someday :)

Step 1: Install create-guten-block

We will first install create-guten-block globally, like so:

npm install -g create-guten-block

In theory this should work no problem, but that's not realistic. create-guten-block requires a minimum of Node version 8 and npm 5.3, so if you haven’t updated either of them for a while, that’s one possible error (and here’s one possible solution).

I always start by pasting my console error into a search engine and removing line numbers and file names to keep my query general. In the interest of improving this tutorial, however, I am curious to hear about what went wrong so feel free to post your issue in the comments as well.

Step 2: Create that guten-block

It’s time! Let’s do it! You know what? I’m not going to tell you how because Ahmad’s documentation is so good and there’s no sense in replicating it.

Go here and follow Ahmad’s instructions to create that guten-block in your command line.

You should see something like this when running the command, create-guten-block test, where “test” is the name of my block. Step 3: Activate the plugin

Go to your Plugins screen, activate your new block plugin — it should be called something like test-block — CGB Gutenberg Block Plugin where "test-block" is what you named your block when creating it.

Step 4: That's it! Let’s use our custom block!

So easy! Now, go to the editor view of a post or page, locate your block, and insert it.

Although I named my block “test”, searching “test” in the block selector yielded the wrong result as you can see in the gif above. The default name of the block is instead “CGB Block” — we will change this very soon!

Text editor setup (optional)

I’ve found it very helpful to have a specific text editor setup for developing blocks. I use Visual Studio Code for my text editor, but I’m sure you can figure out something similar with whatever editor is your preference.

Here are the key ingredients:

  1. Easy access to the command line to keep an eye on build errors (there will be build errors)
  2. A copy of the Gutenberg source from GitHub for code reference (download or clone it here)
  3. Easy access to both your plugin’s directory and Gutenberg’s source directory from #2
??My VS Code setup for Gutenberg development. Notice the integrated terminal and multiple source directories on the right.

In VS Code, I accomplish this using the following features:

  1. The integrated terminal — open with Command + ~ on Mac, or from the menu bar with View > Integrated Terminal
  2. A Workspace containing folders for both your plugin and Gutenberg’s source from GitHub. You can doing this by opening your plugin directory in VS Code, then choosing File > Add Folder to Workspace and selecting the Gutenberg directory you downloaded from the GitHub repo. You can then save the Workspace for easy access with File > Save Workspace As (I called mine “Blocks” in the image above).

This part is optional, and you don’t have to use VS Code. The important thing is having ready access to the command line, your plugin’s source, and the Gutenberg plugin’s source for reference. You can totally reference the source on GitHub if you like, but I enjoy having the files in the same environment for side-by-side comparison and easy searching with Find In Folder.

We are using Gutenberg from the plugin repository for the actual functionality, but that instance only includes the compiled files. We want to reference the source files, so we need to use the codebase directly from GitHub. If you'd like to access updates before they are released in the plugin, you can clone the repository. It would be totally possible to build and work from the GitHub version, but for simplicity’s sake, we are using the plugin version in this tutorial.

Once you are ready to go, make sure you are cd'd into your block’s plugin folder and run npm start. You should see a satisfying message indicating the process has started:

After running npm start in our plugin folder, we are officially “Watching for changes…” (and we didn’t have to touch any config! Cheaters...)

I’m using Wes Bos’s theme for Cobalt 2 in VS Code as well as the same theme for ZSH in my Terminal and iTerm. This makes absolutely no difference in how the technology works, but it does make a difference, on a personal level, to customize your workspace and make it feel like your own (or Wes Bos’, in my case).

What's what

Now that we are in code mode, let’s take a look at the files we’ll be working with. I’ll borrow this from the create-guten-block Readme for reference:

??? test-block ??? plugin.php ??? package.json ??? README.md | ??? dist | ??? blocks.build.js | ??? blocks.editor.build.css | ??? blocks.style.build.css | ??? src ??? block | ??? block.js | ??? editor.scss | ??? style.scss | ??? blocks.js ??? common.scss ??? init.php

For the purposes of this tutorial, we are only concerned with what is inside the src directory. We will not touch anything in dist (those are compiled files), plugin.php, or any stragglers such as package.json, package-lock.json, or.eslintignore.

plugin.php officially alerts WordPress of our plugin’s existence. It requires src/init.php, which is where we’ll write any PHP we need for our block(s). In general, we won’t write anything in plugin.php — out of the box, the only code it contains are the comments to register our plugin.

Let’s drill into src:

??? src ??? block | ??? block.js | ??? editor.scss | ??? style.scss | ??? blocks.js ??? common.scss ??? init.php

The block directory contains files for single, individual block. This includes:

  • block/block.js — All the JavaScript for the individual block.
  • block/editor.scss — Sass partial for styles specific to the editor view,
  • block/style.scss — Sass partial for styles specific to the front-end view, i.e. what you see when you view your page/post.

Now, open up src/blocks.js:

I think of src/blocks.js as a table of contents for blocks, similar to the role of an index.scss or main.scss in a Sass project structure. If we wanted to include two blocks in our plugin — let’s say this was a suite of custom blocks — we could, in theory, duplicate the block directory, rename it, and add something like this to src/blocks.js:

import 'new-block/block.js';>

Then, whatever create-guten-block has prepared for us behind the scenes would know to include our new block's block.js in the main script file compiled into dist (now is a good time to take a peek into dist, if you haven't already).

Not too bad so far, right? We still haven't really gotten to any JavaScript...

A challenge!

Okay, now it’s time for a challenge! Open up src/block/block.js and take a couple of minutes to read through the author, Ahmad’s, excellent comments.

Then, see if you can figure out how to*:

  1. Change the name of your block, that is, the one that shows in the block selector
  2. Change the icon of your block (❤ Dashicons)
  3. Change the text that displays on the front end i.e. when you “View Post”
  4. Change the text that displays on the back end i.e. editor view
  5. Give the front end view a border radius of 30px
  6. Give the editor view a gradient background
  7. Make the text in first paragraph tag editable

* You should be able to work through (almost!) all of these in about 10 minutes. ;-)

How was that?

What problems did you run into? Did you get tired of reloading the editor? Did you see the “This block appears to have been modified externally” message more often than you’d like? I sure did, but such is life with new technology — there's a lot to be desired in the developer experience, but this isn't a priority for the team at present and will come in the later stages of Gutenberg's planned development.

Most importantly, did you get #7?

If you did, then you should be writing this tutorial! That one was a gotcha. I hope you felt at least a little confused and curious because that’s how we learn! We’ll get to that in Part 3.

Now that we have our bearings, let's dig deeper into this notion of a block.

Skeleton of a block

Here is block.js with the comments stripped out — what we might call the skeleton of a static block:

// Stripped down version of src/block/block.js // PART 1: Import dependencies import './style.scss'; import './editor.scss'; // PART 2: Setup references to external functions const { __ } = wp.i18n; const { registerBlockType } = wp.blocks; // PART 3: Register the block! registerBlockType( 'cgb/block-test', { // Part 3.1: Block settings title: __( 'test - CGB Block' ), icon: 'shield', category: 'common', keywords: [ __( 'test &mdash; CGB Block' ), __( 'CGB Example' ), __( 'create-guten-block' ), ], // PART 3.2: Markup in editor edit: function( props ) { return ( <div>You’ll see this in the editor</div> ); }, // PART 3.3: Markup saved to database save: function( props ) { return ( <div>This is saved to the database and returned with the_content();</div> ); }, } );

Let’s do a side-by-side comparison with another static block, the “Separator” block from the default blocks included in Gutenberg. That file is is located in gutenberg/blocks/library/separator/index.js. If you have the folder open in either VS Code or Sublime, you can use the shortcut Command + Option + 2 on a Mac, or View > Split Editor to get the files side-by-side.

If you are following the text editor setup outlined previously, you should have something like this:

In this image, I copy/pasted the above stripped-down version of the block into an empty file to compare it without the comments. That's optional!

What similarities do you notice? What differences? Open up a few of the other block directories inside gutenberg-master/library/, and take a peek into their files, comparing them to our block skeleton. Spend a few minutes reading the code and see if you can spot some patterns.

Here are a few patterns I noticed:

  1. There are curly braces in variable declarations and function arguments all over the place.
  2. Markup appears inside of return statements and often contains made-up tag names (you might recognize these as React components).
  3. All blocks seem to have a settings object containing entires for title, icon , category, etc. In the library blocks, they appear in an export const settings = ... object, whereas in our plugin block, they are part of an argument for registerBlockType.
  4. All blocks have functions for edit and save as part of the settings object.
    • The syntax for the functions is slightly different than our block’s editand save functions:
      • edit( { className } ) { ... } in separator/index.js
      • edit: function(props) { ... } in our block.js
    • The library blocks appear to reference attributes and instead of props
  5. All blocks in the library contain an index.js. Some contain a block.js or other files that appear to contain a definition for a class extending a Component, e.g. class LatestPostsBlock extends Component { ....

What did you find? Feel free to contribute in the comments (but don't stop reading here!).

A somewhat brief and relevant tangent

You probably noticed a statement importing @wordpress/i18n in every index.js and block.js file in the library, as well as a reference to wp.i18n in our plugin’s block.js. i18n stands for internationalization just like a11y stands for accessibility. Internationalization refers to the practice of developing your application to be easily translated to other languages. Since we want to prepare all static text in our blocks for translation, we assign wp.i18n to an alias of __for brevity, very much like we use the $ as an alias for good ‘ol jQuery. Read more about i18n for WordPress here

It’s also worth mentioning where that wp in wp.i18n is coming from and why it’s referenced as @wordpress/i18n in the Gutenberg source. wp is a global object — global meaning a variable available everywhere — containing all of WordPress’ publicly available JavaScript API methods. To demonstrate this, open up the console while on a page within the WordPress admin. Type wp and hit Enter. You should see something like this:

So, anytime we reference something within that wp object, all we are doing is accessing some functionality the WordPress JavaScript API provides us. @wordpress/i18n in the Gutenberg source is doing the same thing, but its importing the functions from an npm module rather than the global object. The functions in the wp global have been intentionally exposed to the public API by the WordPress core developers for use in themes and plugins.

If you are anything like my internal critic, you might be thinking, “Whatever, Lara, I don’t care about those details. Just tell me how to make a cool block with all the JavaScript already!” To which I would reply:

There are so many moving parts and new concepts in this environment that, I’ve found, the more code I take for granted, the more frustrating and time-consuming the process becomes. Approach every line of code with curiosity! If you don’t know what it does, do a Find in Folder in the Gutenberg source and see if you can find a trail to follow. For me, at least, this has been a much more enjoyable way to approach unfamiliar code than trying to build something haphazardly with copy and paste.

Screencast

Here's a screencast where I walk Geoff Graham though the concepts we've covered in this post.

Homework

What? Homework? Heck yes, there is homework! In Part 3, Andy &#x1f349; will dive into modern JavaScript goodies: React, JSX, and ES6 syntax. Although our series is written for those relatively new to JavaScript, it is helpful to learn the code and the concepts from many different angles and resources.

In an effort to introduce some concepts early on, here is an outline for some “Homework” prior to Part 3:

1. Spend some time (1-2 hours) on a React tutorial, or until you can explain in your own words:
  • The render method in React
  • JSX and that those made-up tag names map to JavaScript functions
  • Why React uses className instead of class

Recommended resources:

I'd also recommend reading React State from the Ground Up here on CSS-Tricks, by Kingsley Silas, because it specifically dives into state in React. If you are brand new to React, this will be a lot to digest, but I think it's worth getting it into your brain ASAP even if it doesn't make sense quite yet.

2. Understand ES6 Destructuring and find a few examples of it in both the Gutenberg source and our plugin (that won’t be hard).

Recommended resources:

3. Be comfortable with conditional or ternary operators.

In a sentence, ternary operators are shorthand for if...else statements. You’ll see these all over the Gutenberg source — find some simple examples that provide a fallback for a string’s value, as well as more robust uses like in blocks/library/paragraph/index.js, for example.

Recommended resources:

  • The MDN article is very good.
  • Also look into the not not operator — here is a Stack Overflow post about it.
  • Not to get too far down this rabbit hole, but if you are extra ambitious, do some research about type coercion in JavaScript. This article on FreeCodeCamp and this chapter from You Don’t Know JS by Kyle Simpson are solid starting points.

Okay! Thank you so much for reading, and see you in Part 3 for React, JSX, and other goodies.

Comments

Was there any part of this tutorial that didn't make sense? Did you get lost anywhere? We'd love to keep making this better, so please let us know if any part of this was hard to follow or if any information is incorrect or out of date.

Thank you, again, and good luck!

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block (This Post)
  4. Modern JavaScript Syntax
  5. React 101
  6. SSetting up a Custom webpack
  7. A Custom "Card" Block

The post Learning Gutenberg: A Primer with create-guten-block appeared first on CSS-Tricks.

?Build live comments with sentiment analysis using Nest.js

Css Tricks - Tue, 05/22/2018 - 3:59am

(This is a sponsored post.)

Interestingly, one of the most important areas of a blog post is the comment section. This plays an important role in the success of a post or an article, as it allows proper interaction and participation from readers. This makes it inevitable for every platform with a direct comments system to handle it in realtime.

In this post, we’ll build an application with a live comment feature. This will happen in realtime as we will tap into the infrastructure made available by Pusher Channels. We will also use the sentiment analysis to measure whether comments are positive or negative, and display this information on an admin panel.

Direct Link to ArticlePermalink

The post ?Build live comments with sentiment analysis using Nest.js appeared first on CSS-Tricks.

Dark theme in a day

Css Tricks - Mon, 05/21/2018 - 10:51am

Marcin Wichary has written a great piece that dives into how he used CSS Variables to create a night mode and high contrast theme in an app. There’s so many neat tricks about how to use CSS Variables (Chris has also looked at theming) as well as how to organize them (Andras Galante has an interesting take on this) in here. Plus, Marcin shares some tricks about using filters to invert the color of an image.

I also also love this part of the article where Marcin writes:

I was kind of amazed that all of this could happen via CSS and CSS alone: the colours, the transitions, the vectors, and even the images...

CSS is mighty powerful these days, and it’s posts like Marcin’s that remind me it wasn’t that long ago that theming an app like this would’ve been impossible.

Direct Link to ArticlePermalink

The post Dark theme in a day appeared first on CSS-Tricks.

Guerrilla Usability Testing: How To Introduce It In Your Next UX Project

Usability Geek - Mon, 05/21/2018 - 7:20am
When it comes to user research, sometimes you have to invest more to get more. Other times, you can avoid the expense. Take this Google statistic for instance: did you know that 85% of core usability...
Categories: Web Standards

Learning Gutenberg: What is Gutenberg, Anyway?

Css Tricks - Mon, 05/21/2018 - 3:47am

Gutenberg is the new React-driven SPA editing experience in WordPress. Oh wait, a string of buzzwords doesn't count for a viable explanation of software? We’re going to unpack that string of buzzwords as we explain what Gutenberg is.

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway? (This Post)
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101
  6. Setting up a Custom webpack
  7. A Custom "Card" Block (Coming Soon!)

First, a before-and-after screenshot might drive home the idea for you:

On the left, the editor as it exists pre-Gutenberg. On the right, with Gutenberg enabled via plugin. Buzzword #1: Editing Experience

Gutenberg is a redesign of the WordPress WYSIWYG editor.

The editor in WordPress has traditionally been that single WYSIWYG field, (the blob of content) that saves the entire content of the post to the post_content column in the wp_posts database table. Gutenberg doesn’t change this: it saves all the post content to the post_content table to be retrieved by calling the_content() in our PHP templates.

So yeah, Gutenberg is just a redesign of the editor... but it's a travesty to call Gutenberg just a redesign of the editor! It is so much more than that!

Gutenberg introduces an entirely new way of thinking about content in WordPress. It not only gives developers a native way to handle content in chunks (we’ll actually be referring to them as blocks, which is their official name), it enables end-users to create rich, dynamic page layouts with WordPress out of the box. Without Gutenberg, this would likely require a hoard of third-party plugins (read: shortcode vomit and server strain) as is currently the case with what will be known as the WordPress “Classic” editor.

For the purposes of this article and our learning, know this: Gutenberg does not change how WordPress functions at its very core. It is 99% a change to the editor's user interface. Hitting "Publish" still saves content to post_content—there's just a lot more opportunity to craft the user experience of writing and editing content.

Buzzword #2: SPA

Translation: Gutenberg is a Single Page Application within WordPress.

In a Single Page Application (SPA) an application runs on a single page load, and subsequent interactions are driven 100% by JavaScript and Ajax requests.

Note the "within WordPress' part of the above statement—Gutenberg does not (currently) impact any part of WordPress beyond where one would normally see the editor. In essence, Gutenberg replaces the WYSIWYG, TinyMCE editor with an SPA.

This means that writing content in Gutenberg is fast and satisfying, and I wish I could say my (limited) experience with developing blocks has been the same. For our journey, this SPA business means slow page loads during development (we are loading a lot of JavaScript), obscure and frustrating console errors, and npm modules for days.

Of course, that’s a glass-half-empty look at the situation. Glass half-full? It feels really good when something works. The wins are few and far between at first, but stick with it!

Buzzword #3: React-driven

Translation: Yes, Gutenberg is built in React. That’s probably not going to change anytime soon, if ever.

There was some #hotdrama back in September-October of 2017 about choosing a framework for WordPress since Facebook added a patent clause to React. But after major backlash from open source communities, including WordPress (which, ahem, powers ~30% of websites), Facebook changed it back.

As of January this year (2018) there were still whispers that a framework decision for core is pending, but until we get official word from the powers that be, let’s look at the facts.

  • Gutenberg is in active development.
  • Themes and plugins are in active development preparing for Gutenberg.
  • All of that is happening in React.

I’m putting my money on React, and if that changes, great! I’ll have React on my resume and get on to learning whatever its replacement may be.

Important Resources
  1. The GitHub repo — This is mainly for searching issues when they come up during development to see if they have already been filed.
  2. The Gutenberg Handbook — This is where the official Gutenberg documentation lives.
Beware!

While the Gutenberg project is far enough along that there will not be any major infrastructural changes, we must remember that Gutenberg is brand new software in active development and anything could happen. Why not be on the front lines? This is exciting stuff.

The WordPress community has already begun to take up the task of creating tools, tutorials, case studies, courses, and community-contributed resources.

That being said, you may search a question that hasn’t been asked before. At some point, you will probably find yourself reading the Gutenberg source code for documentation, and you may find the existing documentation to be out of date. You may test out an example from a two-week-old tutorial only to find it uses a deprecated API method.

If you do come across something you feel is not as it should be, research and report the issue on GitHub, ask about it in the #core-editor channel of the WordPress Slack, or alert the author of the aforementioned out-of-date blog post. And if it’s documentation that’s a problem, you can always fix it yourself!

Setting Up

Now, I’d like for you to set up a development environment so that we can continue this discussion with more context. Do these things:

  1. Set up a local WordPress install, however you choose to do that—this can be an existing project, or a fresh install. Just something that can be very broken for demo purposes.
  2. Activate a relatively simple theme. Twenty Seventeen will work just fine. The only thing your theme needs to have is a call to the_content(); in its post and page templates, and most out-of-the-box themes do.
  3. Install Gutenberg. You can find it in the plugin repository. This version is quite far along and updated regularly, so we don’t need to worry about working from a development build.
  4. Activate the Gutenberg plugin and create a new post.

If you haven’t run a WordPress site locally before, check out this guide. We strongly recommend that you download something like MAMP, XAMPP, or similar if this is your first time.

Let's Explore

You should have something a lot like this:

A mostly blank post in Gutenberg. Typing / reveals the block selector.

As in the above image, typing a / reveals a list of blocks. Erase that / and on the right you should see a + that, when clicked, will reveal an additional listing of blocks, organized by category.

A different view of blocks, this time organized by category.

Notice the panel on the right with tabs for both "Document" and "Block." The "Block" tab is known as the block inspector, and gives us a nice area for block specific options like so, for the paragraph block:

The block inspector reveals customization options for a specific block.

I recommend playing around with your post for a few more minutes and testing out the different types of blocks. Keep an eye on that inspector sidebar to see what customization options each block offers. All of these blocks you see now are included in a a library of core blocks and can be a reference point for creating custom blocks (which we will do in the next part of this series!).

After you’ve created a post populated with five-ish blocks of varying kinds, save and publish the post, then take a look at it from the front end. Nice!

Now, let’s do something crazy. Deactivate Gutenberg from the Plugins screen. Go back to the edit screen for that post, and you should see something like this, in the "Classic" editor:

Blocks, as they are saved in the database.

What are all these comments? Those are blocks! They map one to one with the blocks you chose when creating the post.

Under the hood, blocks are chunks of HTML identifiable by their surrounding HTML comments. In the example above, you’ll notice a few of the block names, i.e. wp:block-name are accompanied by JSON, such as the second paragraph block. When I specified some customization options in the block inspector, these were stored along with the block identifier so that now, when I reactivate Gutenberg, my settings won’t be lost; they are saved right alongside the block definition itself.

Before you reactivate the plugin, however, view the post again from the front end. Did you lose some styling? I did.

Go ahead and reactivate the Gutenberg plugin, and double check the editor to make sure your blocks are still intact. Because of those HTML comments, they should be!

Now, let’s poke around and see where these styles are coming from. When I inspect my paragraph block from the front end, I see a few inline styles—a result of options selected in the block inspector—as well as some structural styles from what appears to be a style.css file enqueued by the Gutenberg plugin (after 5.0 is released, remember, this will be just from WordPress, not a plugin).

Inspecting the styles from the front end, we see there are styles coming from Gutenberg itself

Now, try inspecting that paragraph block from the editor view. You should see the same set of inline styles and the same p.has-paragraph selector applied to the block from the editor view. Interesting!

This introduces the fact that blocks can have shared styles between the theme’s front-end and the editor. Pre-Gutenberg, we had theme, or front-end, styles, and we could separately enqueue an editor-style.css to add CSS to the WordPress admin area. Now, however, our blocks share styles between the front-end and the editor view pretty much by default.

Glass half-full perspective: this allows us to craft a content view for publishers that is much closer to what they will see on the front end. They will no longer need to hit the Preview button a dozen or more times to view small content changes before publishing.

Glass half-empty perspective: This could create more work for us—as designers and developers, we now have an editor experience to create in addition to the front-facing website! And we have to figure out which styles are shared between the two. However, I would argue that with a well thought-out design and front end strategy, this won’t be as much of an issue as you’d think.

Umm... Where's the JavaScript?

We’re going to need JavaScript to create a block in Gutenburg. So let’s make a block already! That's the focus of the next post in this series.

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway? (This Post)
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101
  6. Setting up a Custom webpack
  7. A Custom "Card" Block (Coming Soon!)

The post Learning Gutenberg: What is Gutenberg, Anyway? appeared first on CSS-Tricks.

Learning Gutenberg: Series Introduction

Css Tricks - Mon, 05/21/2018 - 3:00am

Hey CSS-Tricksters! &#x1f44b; We have a special long-form series we’re kicking off here totally dedicated to Gutenberg, a major change to the WordPress editor. I’ve invited a dynamic duo of authors to bring you this series, which will bring you up to speed on what Gutenberg is, what it can do for your site, and how you can actually develop for it.

Who this is for

This series is more for developers who are curious about this new world and wanna get started working with it. This series isn’t necessarily for site owners who want to know how it’s going to affect their site or who are worried about it for any reason.

It’s clear there is a lot of possibility with Gutenberg. Yes, it’s aiming to be a better editing experience, but it also likely to change how people think of what’s possible with WordPress. With the custom “blocks” that content will be built with (don’t worry, we’ll get into all this) it’s almost the WordPress editor becomes a drag-and-drop site builder.

I’d recommend listening to this episode of ShopTalk to hear more about all this potential.

How this series came to be

Funny story really. It just so happened that two authors I work with regularly were both independently creating long form series about this exact topic at the exact same time. Shame on me, because I didn’t put 2 and 2 together until both of them had made significant progress. It would have been too weird to release both series independently, so instead, we all got together and worked out a way to combine and rework the series and make a single series that’s the best of both.

Here we are with that!

Prerequisites

You’ll probably do best with this series with these skills:

  • WordPress development concepts such as actions, filters and template tags
  • Foundational (not deep) JavaScript knowledge e.g. understanding the difference between an object and an array and what callback functions are.
  • Using the command line to navigate directories and run build tasks

If you've written your own npm modules, feel totally comfortable writing commit messages in Vim, or you're an old-hat at React, then this series might move a little slowly for you.

Meet your teachers

From here on out, I’m passing this series over to the authors and your Gutenberg teachers: Lara Schenck and Andy Bell.

A bit from Lara

Hi! Back in 2015, Matt Mullenweg, the co-creator of WordPress, instructed a room full of over a thousand WordPress developers, business owners, end users, designers, and who knows how many more live-stream and after-the-fact viewers to "learn JavaScript deeply."

I was in that room, and I remember thinking:

I can do that! I'm not sure why, jQuery has suited me just fine and I really like CSS the best, but okay, Matt, I'll put that on my list of things to do...
—Me, in 2015

The thing is, it's entirely possible to build pretty awesome and robust WordPress themes without touching a byte of JavaScript. Needless to say, I didn't get around to learning JavaScript deeply for a good year and a half, so now I'm playing catch up... and I'm sure I'm not the only WordPress developer in that boat.

Back to the present. Not only has it continued to take over the web in a very big way, JavaScript—in all it's bundled, destructured, spread-operator-ed glory—has made its way into the inner workings of WordPress by way of the editor revamp named Gutenberg.

If you're reading this, I'm assuming you've at least heard of Gutenberg, but if not, here's a rundown by Chris from a few months back that should help orient you. I'm also assuming you feel some mixture of ignorance, intrigue, excitement, and panic when thinking about Gutenberg and what it means for WordPress, ergo ~30% of websites. I'm here to tell you to scrap the panic and keep the excitement and intrigue because this is very exciting for both us developers and WordPress itself.

I predict that, in the coming years, the adoption of Gutenberg will cause WordPress to outgrow its unfortunate reputation as a legacy, insecure, developer-unfriendly, blogging engine. Case in point:

I think I’m gonna make my personal website a WordPress site again. Coming full circle after 6 years &#x1f60a;

— Rach Smith &#x1f308; (@rachsmithtweets) February 20, 2018

I’ll jump in here too and say that Gutenberg has pulled me back into WordPress because the stack is more friendly to me, a front-end developer. Before, I would fumble through customizations, whereas now I’ll very happily roll out custom blocks. To me, Gutenberg is more than an editor—it’s a movement and that makes folks like me really excited about the future of WordPress.

Little ol' WordPress is catching up, and it's bringing with it all the JavaScript goodness you could possibly imagine: Gutenberg is a React-driven SPA editing experience poised to be released in WordPress Core later this year, in version 5.0. It will flip the WordPress ecosystem upside down and, hopefully, make way for a new generation of themes and plugins powered by blocks—a phenomenon other content management systems have embraced for some time.

This means two things for the developers like myself who neglected to “learn JavaScript deeply” back in 2015:

  1. There's still time.
  2. We now have a very specific, real-world context for our learning.

This is great news! I’ll speak for myself, but I find it much easier to learn a technology when I have a specific application for it. With that, I invite you to join me on a journey to "learn Gutenberg deeply" and, in lieu of that, a solid chunk of JavaScript and React.

This topic of this series is not original. The WordPress community has already risen to the task of creating excellent resources for Gutenberg development, and I recommend you read and watch as many as you can! While this series covers some of the same information, the goal here is to structure the content in a way where you, reader, have to work a little bit to get the answers—sort of like class or guidebook with questions and homework.

Yes, we will create a block, but along the way we'll stray from the block-building and learn about the environment setup, about APIs, and other development concepts and terminology that took me a good while to understand. At the end of the day, I hope to help you feel more confident experimenting with code when there isn't airtight documentation or loads of Stack Overflow posts to fall back on.

A bit from Andy

The new, upcoming WordPress editor is bringing a wealth of opportunity to content producers and developers alike, but with that, it brings a whole new JavaScript powered stack to learn. For some, that’s causing some worry, so I thought I’d get involved and try and help. We’re going to dive into some core JavaScript concepts and build out a custom block that will power a classic design pattern—a card. This design pattern gives us plenty to think about, such as variable content and media.

Before we dive into that, we’re going to look at the new JavaScript stack and the tools that it gives us. We’re also going to take a look a React component to give us a primer of reactive, state-driven JavaScript and JSX.

With all of the knowledge and tools that we worked with, at the end of this tutorial series, we’ll have a solid custom card block. This can also work as a baseline for so many other types of block for maintaining website content.

Before we dig in, let’s get our machines set up with the right tools to do the job. Because we’re using the modern JavaScript stack, there are some browsers that don’t yet support the language features. Because of this, we’ll be using some Node JS-based tools to compile this code into a more cross-compatible form.

Get Node JS running

Our setups vary wildly, so I’m going to point you to the official Node JS website for this, where you’ll find handy installers. There’s a really useful page that explains how you can use popular package managers too, here.

Get your terminal running

We’re going to be using our terminals to run some commands later in the series, so get yours setup. I like iTerm, but that’s only for Mac so here’s some resources for both Mac and Windows users:

  • Mac: You can use the default terminal which is located at Applications > Terminal
  • Windows: You can either get the Linux subsystem running, use command prompt or get software like Hyper
Get a local WordPress instance running

Because we’re using the modern JavaScript stack, it’s important to get an instance of WordPress running locally on your machine. If you haven’t done that before, check out this guide. I strongly recommend that you download something like MAMP, XAMP or similar if you’re new to this.

Once you have a local instance running, have a theme ready to play with as we’ll be diving into a little bit of theme code later on.

Modern JavaScript can be daunting if you’re not working with it day-to-day, so together, we’re going to dig in to some core elements of the modern version of JavaScript: known commonly as ES6.

We’re then going to take that knowledge and use it to build a React component. React is an incredibly popular framework, but again, it’s quite daunting, so we’re going to dig in together to try and reduce that. The Gutenberg JavaScript setup very much resembles React, so it’s also an exercise in getting familiar with component based, reactive JavaScript frameworks in general.

Once we’ve covered that, I’m hoping you’re going to be feeling pretty awesome, so we’re going to take that momentum and dive into the sometimes dreaded, webpack, which is a tool we’re going to use to process our JavaScript and smoosh it together. We’re also going to get Babel running, which will magically turn our ES6 code into better-supported ES5 code.

At this point, I think you’ll be full of confidence in this stack, so we’re going to get stuck into the main course—we’ll build out our custom card block.

Sound good? Awesome. Let’s dive in!

Article Series:
  1. Series Introduction (This Post)
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101
  6. Setting up a Custom webpack
  7. A Custom "Card" Block (Coming Soon!)

The post Learning Gutenberg: Series Introduction appeared first on CSS-Tricks.

Syndicate content
©2003 - Present Akamai Design & Development.