Corey Collins, Author at WebDevStudios https://webdevstudios.com/author/corey/ WordPress Design and Development Agency Mon, 15 Apr 2024 16:00:17 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.2 https://webdevstudios.com/wp-content/uploads/2022/07/cropped-wds-icon.white-on-dark-60x60.png Corey Collins, Author at WebDevStudios https://webdevstudios.com/author/corey/ 32 32 58379230 Improve Your Website Strategy Now https://webdevstudios.com/2021/06/01/improve-your-website-strategy-now/ https://webdevstudios.com/2021/06/01/improve-your-website-strategy-now/#comments Tue, 01 Jun 2021 16:00:43 +0000 https://webdevstudios.com/?p=23362 Everybody needs a strategy, and since your website (probably) can’t think for itself, it’s going to be up to you to figure out what your website’s strategy is. So, what exactly is a website strategy and how do you get one? Whether you already have a website strategy you want to improve or you’re starting Read More Improve Your Website Strategy Now

The post Improve Your Website Strategy Now appeared first on WebDevStudios.

]]>
Everybody needs a strategy, and since your website (probably) can’t think for itself, it’s going to be up to you to figure out what your website’s strategy is. So, what exactly is a website strategy and how do you get one? Whether you already have a website strategy you want to improve or you’re starting from scratch, we can help you get to where you need to be.

Today, we’ll talk about four pillars of focus for your website strategy:

  • Defining your users
  • Defining your user paths
  • Defining your site structure
  • Defining your content strategy

But first: what is a website strategy? In its most basic definition, a website strategy is the plan you’re following to achieve whatever goal it is you’ve set for yourself. Do you want to attract more visitors to your website? Do you want to increase users’ time on site? Do you want to sell more of a product or service on your website?

With a strategy in place, you can focus on actionable paths and items to achieve your wildest fantasies (okay, maybe they’re not all that wild). Having a strategy alone isn’t going to get you to where you need to be, though; you’re also going to need to execute on that strategy.

So, let’s begin with one of our four pillars to see just how we can begin building a strategy to execute.

Defining Your Users

This is a candid photograph of a woman smiling as she reads the screen of her iPad.Before you can think about what the goals are for your website, you need to think about the users for whom your site is built. Knowing your users, their goals, and how they use your website will guide you toward making decisions with them in mind, which helps you establish your website strategy.

Who is your current user base? How do they even use the website—on a phone, a tablet, or a computer?

If you’re selling a product or service, do you know who your customers are? Do they predominantly fall into a specific age group, and if so, are you tailoring your content to that age group?

If you don’t know the answers to questions like these, it’s time to dig into your analytics—whether those are specific to your website or, if you’re someone who sells a physical product or service in stores, extend to the real human people spending their time and money with you.

A helpful exercise to get the ball rolling is to define personas. A persona is a made-up representation of a person who uses, or may use, your site. Their behaviors and traits may be based in reality, but their names, photos, and personal details are generally a facsimile of their real-life counterparts.

You’ll want your personas to represent the users you either are already targeting and hope to retain or, possibly, new types of users who you are hoping to have walk through your virtual door.

Personas can be defined in several different ways: you can either utilize the existing data and analytics you have to establish your personas, or you can dive in a bit deeper and run interviews or focus groups with your existing user base. With the latter, you’ll be able to receive more real-world feedback, though not everybody will have the time and resources to run a focus group. Once your personas are defined, it’s time to figure out exactly how these users are supposed to work their ways through your website.

Defining Your User Paths

This is a nature photo of a wooded area with two paths diverging.The moment you know your users and their needs, you can begin to map out the user paths. Defining your user paths is a massively important step of your website strategy. In fact, it should be done before beginning designs or even wireframes. You don’t want to just throw a hero there and a call to action there without thinking about whether or not those elements should even be on a page in the first place. A design process without fleshed out user flows runs the risk of turning out a scattered and confusing final product.

But, what is a user path? A user path, put succinctly, is the flow a user follows as they navigate your website. If your end goal is for a user to sign up for an email newsletter, how do they get from landing on your website to signing up for the newsletter? If your end goal is for a user to make a purchase, which path does the user follow to ensure they’re presented with all of the information they need to complete the transaction?

Based on your research, you should know the reasons your users are coming to your website. Whether it’s informational, to purchase products, to interact with a community, or any other number of reasons, your research should be able to tell you exactly who your users are and how they use your website.

That isn’t all you’ll want to know, though. As much as you need to serve the needs of your users on your website, you also need to serve the needs of your business. Don’t get so tied up in defining all of your user needs that you forget your own business needs.

You may have a new product or service launching that you’re going to want to push users towards, or you may be pivoting away from one aspect of your business to another. Without negatively affecting the experience for your existing users, you may need to focus on how to drive your own objectives; and these may be different from anything your users have talked about during your research phase.

It’s also important to consider brand new users. Your business objectives may be easy to communicate to the users you’ve had for years, but how will you communicate your objectives and goals to someone who is seeing your website for the first time? How will you educate, inform, and lead these brand new users so that they can follow the correct path to find what they need?

Another important factor to consider with brand new users is the way they got to your site in the first place. Did they see a promoted post on social media? Did they click on a paid ad somewhere else online? Did they find your site through an organic search?

The way users get to your site is important, as well, and may need to be tailored for each medium. For a user who finds your site through an organic search, the homepage may not be the first page they land on. Instead, they may see a single product page. For a promoted social media post or paid advertisement, you may want to send users to a landing page specific to the content of the ad rather than pushing them to the homepage without any guardrails. If your aim is to convert users to signups or purchases, you’ll want to ensure that you’re doing everything in your power to guide them to the correct spots from the very beginning.

The important thing to remember is to guide your users, whoever they are and however they reach your site, to meet two sets of goals: yours and theirs. Along the way, though, you need your website to act as a guide to get the user exactly where they need to be. You don’t want to push a newsletter signup or product purchase call to action too quickly. You’ll want to make sure the user has been provided with the proper information flow so that they can make an informed decision once they land at the final step of their intended user flow.

Defining Your Site Structure

This is a low-light photograph of the exterior of a modern designed home to exemplify structure.So, now that you’ve got your user paths mapped out, it’s time to move on to thinking about your site structure. A decent amount of this work may be done for you already. If you already have a website, you should have a solid starting point. You may already know the pages and relationships you want to keep while identifying other pages that are low performers and can either be completely axed or swallowed up into other pages.

Another chunk of this work is going to be laid out by way of your work on user paths. By defining the paths you want your various users to follow, you’re going to essentially be creating something akin to a sitemap or flow chart of pages and content.

Don’t stop there, though. It’s great to have an understanding of your heavy hitters like your homepage, landing pages, and product pages. What about everything else, though? Are you going to be producing regular content with blog posts? Will you publish case studies, press releases, or other forms of content?

If so, where will this content live and how will a user find it? How will your various types of content interact with one another to bring the user along for the ride? If part of one of your user paths is to show a user a portfolio of your previous work, how are you going to drive them to that portfolio?

You’ll also want to think about when it’s important to show a user specific types of content. If you’re selling a product or service that lends itself to a portfolio page, you may want to bring the user to your portfolio page before driving them to product pages. If your goal is to educate users before leading them to a contact form, how will you structure the content so users can be sure they’ve exhausted their research before filling out a contact form?

Site and content structure are not just where the pages and posts live throughout your site, though. You’re going to want to think about how the content is laid out on individual pages, too. When a user comes to a landing page, especially if it’s their first time on the site, you’ll want them to feel like the content makes sense and provides them with enough information to make an informed decision as to where to go next.

Again, as with your user paths, don’t simply slap content into a website or even a single page without thinking through what that content actually means, what it says to a user, and how it guides them to meet their goals.

Defining Your Content Strategy

This is an interior photograph of a public library filled with books.You know your users. You know how you want your users to use your site. You know how you’re going to arrange and structure the content on your site.

The last piece of the website strategy puzzle is to define your content strategy. By this point, you should know what types of content you’re going to be producing: blog posts, case studies, data visualizations, etc. So now it’s time to think about how, and for whom, that content is going to be produced.

Have you decided to write blog posts for your site? Great! Have you decided who these blog posts are for? Have you settled on a tone or style for these blog posts? Maybe not?

Having an additional content stream outside of landing pages and product listings is a wonderful way to bring users back to your site. While most of your content may be generally static and unchanging, blog posts could be published several times a week. Before you begin writing these posts, though, you need to nail down your audience and writing style.

Are you writing blog posts for users who have never heard of your products or services before? Will these posts be used as a means to educate folks on individual parts of your business before driving them to another part of your site? Will you only publish news and general company information? What about tutorials or real-life testimonials from customers who have used your products or services in the past?

If you’re going to be talking to your audience, how will you talk to them? Are “we” going to be doing something in these blog posts? Am “I” telling you how I’ve done something? Or am I telling “you” what to do and how to do it through a tutorial or educational post?

Keeping a consistent voice, tone, and style in your blog is going to be important so that your users know why they’re coming to your blog in the first place. Of course, you can have different categories of posts for different tones or purposes, but it’s important to know that upfront and to be able to drive users to those specific posts so that they don’t have to hunt and scavenge through your site to find their desired content.

Finally, don’t forget to nail down who is going to be writing your content. Are you a one-person shop running a small business? If so, can you realistically keep up with a steady stream of one or two blog posts a week? If you think you might run out of steam after a few months leaving an abandoned graveyard of decaying blog posts, then it might be beneficial to seek out a dedicated content person or team.

The content doesn’t end once a user leaves your website, either. You may find yourself needing videos, tweets, and stories produced and not enough time to produce them all yourself. Before you get in over your head and dedicate yourself to producing a high volume and/or high quality of content, make sure your plan is sustainable.

Wrapping Up

This is, by no means, an exhaustive list of all of the things you need to think about and do when planning your website strategy. This is just the start of your journey!

What may be the most important piece of the puzzle to remember is this: not every website strategy is going to be the same. The process is going to be different and hold unique challenges for every website and project. You can’t apply a blanket set of rules to every website strategy project, but you can have a set of touchstones to point you in the right directions.

As long as you are thoughtful, listen to the demands and requirements of the project, and tailor your process and deliverables to each site, project, or client then you’ll find the overall rhythm that works for you while still providing an exceptional and distinct end product. When you’re ready to discuss and build your website strategy, contact us. Let’s work together to define your course of action.

The post Improve Your Website Strategy Now appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2021/06/01/improve-your-website-strategy-now/feed/ 1 23362
WebDevStudios Day in the Life of a Technical Strategist https://webdevstudios.com/2020/10/08/webdevstudios-technical-strategist/ https://webdevstudios.com/2020/10/08/webdevstudios-technical-strategist/#respond Thu, 08 Oct 2020 16:00:09 +0000 https://webdevstudios.com/?p=22715 Editor’s Note: Welcome to a new series of blog posts featuring a day in the life of a WebDevStudios (WDS) team member. What’s it like to work at WDS? You’re about to find out. The first in this series begins with Corey Collins, WDS’ first-ever Technical Strategist. Corey is going to walk us through his Read More WebDevStudios Day in the Life of a Technical Strategist

The post WebDevStudios Day in the Life of a Technical Strategist appeared first on WebDevStudios.

]]>
Editor’s Note: Welcome to a new series of blog posts featuring a day in the life of a WebDevStudios (WDS) team member. What’s it like to work at WDS? You’re about to find out. The first in this series begins with Corey Collins, WDS’ first-ever Technical Strategist. Corey is going to walk us through his typical workday at WDS. Read to learn more.

Corey Collins

Job Title: Technical Strategist
Years at WebDevStudios: 9

A portrait photograph of Corey Collins
Corey Collins, Technical Strategist

Before moving into the Technical Strategist role at WDS, I wore a bunch of different hats.

When I first started at WDS, I was a part-time frontend engineer (or, as we were called nine years ago, “designers”). I helped make the web a beautiful place as we experimented building with different WordPress themes, including some of our own creation. This is also where the company began to get a taste of LESS and SASS.

As things evolved, the “designer” term used to encompass frontend engineers faded away and the lines between backend and frontend engineers began to blur. We all began to work more toward our strengths and passions than being pigeonholed as just one thing. This growth, and stepping more and more out of my comfort zone, led to my eventual promotion as a Lead Engineer.

From Part-Time Designer to Lead Engineer

As a Lead Engineer, I led a team of engineers to ensure our projects were completed on time and with a focus on delivering the highest quality of code possible.

As a Lead, my days involved checking in with the team and having a daily standup at some point throughout the day. As teams changed over the years, this would fluctuate from morning to afternoon depending on when it worked best for everybody.

Aside from calls, I’d review code with a frustratingly sharp eye for detail, user test functionality on the frontend and backend, and just generally try and break as much code as possible in as many different ways conceivable to make sure every scenario had been accounted for.

When I wasn’t diving into writing, reviewing, or testing code then you’d probably find me on a client call discussing the weekly updates for a project, running demos of our progress, providing client training, or running full-site QA and user testing on a project from another team.

As our processes continued to evolve, the responsibility of writing project plans for each project shifted to the Leads who would be running the project. This would translate directly to the Technical Strategist role; as it turned out, I was in the very slim minority of Leads who actually enjoyed writing project plans!

Current Status: Technical Strategist

With the move to the Technical Strategist position, I’m not longer writing code most days, aside from working internal projects here and there, or giving back to the community during Five For The Future.

An above view photograph of a person's Converse sneaker-wearing feet on the floor beneath a wood desk where a phone, cup of black coffee, and a laptop sit.My days as a Technical Strategist kick off with the usual check-ins: Slack, emails, and Jira/Confluence. The Strategy department will drop a quick message in Slack to let everyone know what we’re planning to work on that day and if we have any blockers. Then it’s off to the races.

Most days will include calls with clients in some stage of strategy. Along with our Digital Strategist and Digital Designer, we’ll discuss the needs and goals of the client so that we can begin to formulate the game plan for what the team will be building.

This is generally not a single call, especially if we’re going to be doing design work or a hefty data migration. Once we have a solidified data and design plan, though, another step in the process kicks into gear. I’ll begin to review everything we’ve done up to that point—call notes, requirements, goals, and designs.

I’ll usually have some UX questions around the mock-ups leading to conversations with our Design Strategist on how they expected a specific feature or design element to work both for users on the frontend and admins on the backend. This is one of many steps along the way where I’ll get into the nitty gritty of everything to a (probably) annoying degree.

For instance, if we’re building a block with a set of cards with images, headings, and buttons, how does all of that data get populated? Does it come from a post type dynamically? If so, does the admin need to be able to customize the query in any way? What happens if the post for a specific card doesn’t have a featured image set? Or, is the content all manually entered?

The Deep Dive

Digging into the designs and functionality in this way allows me to dive into two of the main sections of the project plan: technical requirements and user stories.

Technical requirements are the details that describe what a feature does and what it means for it to be complete. This will include the “done” criteria for a feature with additional notes for clarification for our engineers and our client.

User Stories detail out how everybody will use this feature. This includes administrators down to any different user roles that may need to be considered as well as users on the frontend. Will a logged-in user use a feature different from a logged-out user? What happens on mobile versus desktop? What are all of the actions that a user can take when using the feature?

A photograph of a hand holding a black magnifying glass over the keyboard of a laptop.Everything we gather, in the way of features, technical requirements, and user stories, gets boiled down into the project plan in Confluence. This includes detailing out every custom post type, each custom taxonomy, custom post meta, page templates, and any other functionality we’ll be building as part of the project.

We also like to include a future enhancements section of the project plan for pieces of functionality that were discussed during the strategy process but, for any number of reasons, will not be included in the first phase of the project. While we won’t be building these features in the first phase, we feel that it’s important to acknowledge that they were discussed along the way.

Once we feel the project plan is complete on our end, we’ll schedule a call with the client to review the plan and make any final adjustments as needed. When the project plan has final sign-off from the client, we’ll schedule an internal handoff call with our engineering team and the reigns are passed to Project Management and Engineering.

Wrapping up my day, I’ll check through Slack to see if anyone has any lingering questions for me, do one more quick pass through my inbox, and drop any end of day updates into any Slack channels requiring me to chime in. Then, it’s off the computer and to rub some pet bellies (take your pick of one of our four cats or two dogs), play some video games (a lot of Stardew Valley and Tony Hawk’s Pro Skater 1 + 2 lately), and catch a show or two (crossing my fingers for no soggy bottoms on The Great British Baking Show).

This isn’t the last I’ll see of the project, though. Once the project is complete, I’ll come back in to run QA and user testing on the site to confirm we’ve met all of the requirements and to test the overall user experience. Anything I log as a ticket in Jira will get addressed by the team before we hand things off to the client for their internal testing and QA.

A Badge of Honor

When thinking about what I like most about the Technical Strategist position, it’s basically everything about the job. I love figuring out how things are going to be built and, for whatever reason, truly enjoy writing the technical requirements and user stories for these features. This seems like a trait that has skipped a lot of other folks, so I’m glad I’ve been able to turn it into a big part of my day job!

A photograph of a pin-on button of a red heart against a white background and the button is laying on a cement ground.I also have a deep love in my heart for QA, user testing, and digging into the UX of a project to get everyone thinking about why we’re doing something a certain way and how it may affect the people actually using the site. We can design and develop something in any number of ways, but which way is best for both the site and the users in order to achieve the overall project goals?

I can’t explain what it is about all of these things I love so much. Maybe it’s my love of solving problems, quietly judging things, and smashing the system. When I find a bug in QA, it’s like a badge of honor for me. The team has built this great thing, and through some wizardry, I was able to find the right combination of actions to take in order to get an unexpected result.

In the end, I’m still helping to deliver a rock solid final product to our clients. I’m just doing it in a different way than I did as a “designer,” Frontend Engineer, or Lead Engineer.

Now that you have an understanding as to what a day in the life of a Technical Strategist at WebDevStudios is like, contact us about building your next website with a strategy and project plan in place. Interested in joining our team? We’re hiring!

The post WebDevStudios Day in the Life of a Technical Strategist appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2020/10/08/webdevstudios-technical-strategist/feed/ 0 22715
Why Digital Strategy Is an Important Part of Your Website Project https://webdevstudios.com/2020/09/24/digital-strategy/ https://webdevstudios.com/2020/09/24/digital-strategy/#respond Thu, 24 Sep 2020 16:00:37 +0000 https://webdevstudios.com/?p=22848 Are you in the market for a new website, but unsure where to start? The WebDevStudios (WDS) digital strategy team can take you from ideas to execution. We have a brilliant digital strategy team (featured in the photo gallery below) that has an ability to identify website project goals, define solutions that will meet those Read More Why Digital Strategy Is an Important Part of Your Website Project

The post Why Digital Strategy Is an Important Part of Your Website Project appeared first on WebDevStudios.

]]>
Are you in the market for a new website, but unsure where to start? The WebDevStudios (WDS) digital strategy team can take you from ideas to execution. We have a brilliant digital strategy team (featured in the photo gallery below) that has an ability to identify website project goals, define solutions that will meet those objectives, and recommend an approach to achieve success in project execution. To put it bluntly, digital strategy is an important part of your website project. It’s the process we use to clarify these questions:

  1. What will your website look like?
  2. How will your website work?
  3. How long will it take to build?
  4. How much does it cost?

Answering these questions and defining the scope of work requires:

  • An understanding of the needs and requirements for the project
  • A series of meetings with the WDS digital strategy team
  • Documentation of a fully realized list of ideas, features, and requirements
  • A precise review of mock-ups provided to ensure all potential scenarios for every user type have been accounted for
  • A plan that targets your timeline and budget
  • A prioritization of the deliverables to ensure a smooth development and release process

WebDevStudios Digital Strategy Team

A selfie photograph of WebDevStudios Director of Project Management, Cristina Holt, while at a fair, wearing a hoodie shirt and sunglasses, and smiling at the camera. A portrait photograph of Corey Collins A selfie style portrait of Jennifer Cooley, Digital Designer. She is wearing glasses and smiling at the camera.

Identify Requirements

The first step of our digital strategy team is to understand your website project goals, the success criteria of your project, as well as the current state of things in your current environment. We’ll do this through a series of collaborative meetings with you over a specified period of time.

Example Client Goals

  • An increase in newsletter subscribers.
  • Improvement and reworking of the user experience
  • Take newly-created website designs and turn them into a working website
  • Push website data to a CRM

During the strategy process, our aim is to uncover things you might not think to consider.

Example Questions We Ask

  • What does your website’s content hierarchy look like?
  • When a user lands on a specific page, what do you want them to do?
  • How will users on your site interact with a particular element?
  • Do you have multiple user types, and do they each have unique ways of interacting with the website?
  • How are specific elements managed on the backend by your administrators and editors?

We also do a deep dive into the actual functionality and technology requirements for your site. For example:

  • Third-party API connections for passing or obtaining user data
  • Support for eCommerce either onsite or through third parties
  • Custom forms
  • Business process automation
  • CRM integrations

Our goal is to exhaust all questions that could be asked in order to bring us to our next step of defining solutions.

Define Solutions

A photograph of a yellow, green, and black dart board with a red dart in the center red bullseye.In the world of technology, there is not always just one way to accomplish something. Once we have identified the goals and requirements for your website project, we can begin to determine how we’ll meet those goals and explore the different paths to meeting them.

The intention of defining solutions is not to choose the first opportunity. Instead, it is to find all opportunities and weigh them against the timeline and budget so that we can make the most educated recommendation. The solutions presented by our digital strategy team are based on our strong technical experience, especially in the WordPress space, and use the most innovative tools and technology.

Recommend Approach

A photography of two people looking at a map with one person pointing a spot on the map.No two projects are the same; so, it is not as simple as defining a single set of tools and workflows for every project. The technologies used to complete those projects may differ as we tailor our recommendations to each individual project.

Our recommended approach will be a combination of a focus on project goals, the timeline that needs to be met, and the budget allocated for the project. The details of the deliverables will vary per project but will always be delivered as a project plan. The project plan is a comprehensive document containing all of the low-level and high-level requirements for the project.

What a Project Plan Includes

  • Design(s), if needed
  • Documented functionality requirements
  • Documented user experience for that functionality
  • Recommended third-party tools, if needed
  • Research and feedback for existing functionality
  • Plan for launching
  • Timeline for completion, including phases
  • Budget requirements

The intention of our digital strategy team is to strip away all possibilities of vague or unclear language around development requirements, so that both of our teams are set up for success. Once the project plan is complete and approved by the client, it will serve as the guide for our engineering team to take the next steps for development kickoff.

When you are ready to start your next website project with WDS and strategize website goals, requirements, and user experience, contact us! We can’t wait for you to meet our extraordinary digital strategy team.

The post Why Digital Strategy Is an Important Part of Your Website Project appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2020/09/24/digital-strategy/feed/ 0 22848
Integrating Advanced Custom Fields + Gutenberg Into wd_s https://webdevstudios.com/2019/10/24/advanced-custom-fields-gutenberg-wd_s/ https://webdevstudios.com/2019/10/24/advanced-custom-fields-gutenberg-wd_s/#respond Thu, 24 Oct 2019 16:00:16 +0000 https://webdevstudios.com/?p=21285 With version 5.8 of Advanced Custom Fields (ACF), a new way to build Gutenberg blocks was introduced. The mission statement of ACF with this pivotal update was to: …radically change the perception of block development in Gutenberg by reducing learning time, hurdles, environment setup and JavaScript knowledge to an absolute minimum. They have done exactly Read More Integrating Advanced Custom Fields + Gutenberg Into wd_s

The post Integrating Advanced Custom Fields + Gutenberg Into wd_s appeared first on WebDevStudios.

]]>
With version 5.8 of Advanced Custom Fields (ACF), a new way to build Gutenberg blocks was introduced. The mission statement of ACF with this pivotal update was to:

…radically change the perception of block development in Gutenberg by reducing learning time, hurdles, environment setup and JavaScript knowledge to an absolute minimum.

They have done exactly that.

For quite some time now, our wd_s starter theme has been powered in part by Advanced Custom Fields. Using the Flexible Content Field, we were able to create a page builder-esque experience for users. This experience lived on the backend when editing posts and pages. We didn’t set out to create a full-on page builder or content builder like the ones we’ve used in the past. We simply understood the need for users to have full control over their content, the placement of that content, and the overall structure of their posts and pages.

And it worked! It worked for a long time. In fact, it still works beautifully.

With the advent of WordPress 5.0, Gutenberg became the hot topic when discussing the CMS. Some absolutely loved the new experience while others reviled it for myriad reasons, such as it felt rushed, it wasn’t fully accessible, and that it was an oftentimes confusing experience.

For us, the issues we experienced working with and building alongside Gutenberg in its development was enough to raise a few red flags. Despite Gutenberg going live in 5.0, we stood back for a moment to evaluate everything before diving head-first into action with the new system. After all, what we had already established wasn’t broken. So, there was no need to “fix” it.

In order to keep our existing workflow in place, we enabled the Classic Editor plugin on new projects to disable Gutenberg and continue working with our tried and true ACF Flexible Content Block system. Once the ACF 5.8 betas and release candidates began rolling out with Gutenberg block support, we began testing the new features with our existing system.

What did we find? Well, to no surprise to anyone on the team, we found that it did exactly what it promised. We were able to spin up new Gutenberg blocks and begin planning a move away from Flexible Content and into a full-on Gutenberg experience.

First Steps

The first thing we needed to figure out when making the transition to ACF-powered Gutenberg Blocks was what we actually needed to include from our existing Flexible Content Blocks. Starting with a blank slate, our content blocks included things like a Call To Action, Hero, and Generic Content block which was a simple WYSIWYG field.

With the robust suite of blocks already available with Gutenberg, we knew we could trim down what we needed to bring over. So, we began to trim the excess and examine if the other blocks we needed served a larger purpose as custom blocks than by “replacing” them with core blocks. We were able to rip the Generic Content block out pretty easily as a standard content block can be added anywhere with Gutenberg.

For our other blocks, though, we found that there were enough little bits and bobbles attached to them that we didn’t want to give up. For instance, our blocks all include the same set of global options including the ability to set a background image, background video, or background color. With the video and image background options, we also include the ability to apply an overlay to make text easier to read when overlaid on the background.

We also have some bonus functionality like Start Date and End Date for those blocks you wish to only display for a specific period of time. Our Hero was also just a bit more fleshed out than what we felt we could accomplish with the core Gutenberg blocks, like setting the aforementioned background options, title, text, and optional link stylized as a button.

Our existing blocks also included Recent and Related Posts. While Gutenberg does offer a Latest Posts widget out of the box, there was just a bit more we were doing with ours that we didn’t want to give up. For instance, the core Latest Posts widget allows for you to specify a post category from which to draw posts but not post tags. You are also limited to selecting a single category or tag, while our block allows for selecting multiple terms in each taxonomy. Along with the previous global block options mentioned and some visual differences, we felt it important to include our own custom block.

Once we got through with our internal review process to determine which blocks we would port over, we were left with:

  • Accordion
  • Carousel
  • Call To Action
  • Fifty-Fifty
  • Hero
  • Recent Posts
  • Related Posts

Creating Your First Block

The first step in creating your Advanced Custom Fields + Gutenberg block is to hook into acf/init and register your block. To ensure that your blocks all have the same global options, though, you’ll first want to establish your baseline supports features for the block:

View the code on Gist.

With this, you’re saying two things: that you only want two layout options for your blocks and that you want to allow for your blocks to have an anchor, or ID, set. In general, the wd_s Flexible Content Blocks had conformed to the width of the content container with the option to go full-width, meaning they will span 100% of the browser width. This is common with blocks with backgrounds, especially heroes. Allowing for an anchor, or ID, was essential as this allows for users to link to other blocks either from the same page or externally.

Next, you’ll need to actually register your block:

View the code on Gist.

This is the important stuff. You’re giving your block a name, description, some keywords, and enqueuing your scripts amongst setting some other baseline ACF settings. Once you have this in place, you simply need to hook in your function like so: add_action( 'acf/init', '_s_acf_init' )

Since you’re calling some other functions and functionality in your block registration, though, you also need to ensure you’re properly tapping into the groundwork Advanced Custom Fields has laid for you.

Adding a Category

In your block registration above, you’ve set your category as wds-blocks. However, that’s a custom category and doesn’t exist by default, which means Gutenberg won’t know how to find these new, fabulous blocks you’re building. Because of that, you need to register your category in a separate function:

View the code on Gist.

Be sure your category slug matches the category name you’re prescribing exactly!

Registering Scripts and Styles

For the Accordion block, you’re calling the _s_acf_enqueue_accordion_scripts callback function to register the scripts necessary to power your block. In general, you may not need to register any scripts—just styles. For the Accordion and Carousel blocks coming form wd_s, though, there is some additional JavaScript needed to make sure the blocks work on the backend.

After all, if you’re looking to deliver a similar experience on the backend as you’re providing on the frontend, you want your JavaScript to work so users can see just how the Accordion collapses and expands before publishing their content. With that in mind, you have to enqueue your scripts:

View the code on Gist.

Within this function, you’re also calling a function to enqueue styles, which looks like this:

View the code on Gist.

You’ll notice the very first thing in both functions is the check for is_admin(). You don’t need to enqueue your scripts anywhere else than on the backend through these methods. The wd_s theme already compiles and enqueues all of the necessary JavaScript and CSS files for the frontend, and here you’re simply concerned with making sure those styles are reflected when adding a block in the editor.

Adding a Field Group

Once your code is in place, the next step is to create the fields for the block. After all, what you’ve done so far is just tell Advanced Custom Fields to create something called “Accordion,” but you’ve yet to actually put something in that block.

Just like with any other Field Group you’d want to create, you’ll navigate to the Custom Fields menu in the Dashboard and click “Add New.” Next, create the fields you need for your block:

ACF Field Group settings page

These will, of course, differ from block to block and for your own personal use cases. All in all, though, this should be familiar to anyone who has worked with ACF in the past. The next step is where things get changed up a bit.

With the previous Flexible Content Block system in wd_s, the “Active” option would be toggled to “Off” for all of the block Field Groups. Then, each block would be cloned in the actual Flexible Content Block Field Group. This helped keep things a bit more sane in the backend. Each block existed as a standalone Field Group, and other reusable Field Groups could be created and cloned into each block like the Background Options and Display Options.

Now, however, you simply need to set your Location rules based on the block you’re creating. Since this is the Accordion block, you want to tell ACF to display these fields when the Block is equal to Accordion. Plus, you now need to ensure you set the Active option to “On” otherwise your block won’t display in the Gutenberg block selector:

ACF Field Group Location settings

And that’s how easy it is to create and register a block in ACF! You can now select your block from the block selector when editing your post… but nothing will happen.

Creating Block Templates

Before anything can actually display, you’ll need to create a template. Ain’t that just the way life works sometimes?

In the block registration way up above in this post, you may have noticed that we’ve set render_callback to _s_acf_block_registration_callback. This is where you’ll let Advanced Custom Fields know exactly where to find the template to display your block.

Keeping with the DRY mentality and not wanting to overload the theme with callbacks for every single block, wd_s includes a handy dandy function which will convert the block name to a slug and inject it into a core WordPress function to grab a template file. This function also checks to make sure the block isn’t expired, which is important because if your block is expired, you don’t want to display it on the frontend at all!

The end result is this tidy little 22-line chunk:

View the code on Gist.

What lives in your actual template file is up to you and will change based on your block, but the important bits to mention are:

  1. Make sure you specify the correct template path
  2. Make sure you name your blocks and template files consistently
  3. In the case of wd_s, add an extra bonus for the Expired Block functionality

Since you have the ability to hide blocks after a specific date, you need a way to communicate this to users on both the frontend and backend. This is easy on the frontend. You simply don’t display the block at all. On the backend, though, you don’t want to hide the block completely because then a user can never edit it or even remove it. That block lives there now forever. It’s comfortable and can’t be evicted. It has attained squatter’s rights.

With a couple of little functions, and some CSS, you’re able to show editors that a block is expired while still allowing them to edit the block in the backend. This is super useful if a user has a block that runs once a week every month and you need to edit the content each month. Now, your users can place your block and let it sit quietly expired with your newest content updates until the new Start Date rolls around.

You’ll begin with this:

View the code on Gist.

And build on that with the following pair of helper functions which check for a block’s expiration and add a class to the block if the block is no longer active:

View the code on Gist.

Now when a block expires, your users will see a helpful notice in the backend:

wd_s Gutenberg expired block message that says, "Your block has expired. Please change or remove the Start and End dates under Other Options to display your block on the frontend.

Our Full Setup

After much back and forth in building, testing, building, testing, and reviewing we are super excited to announce that wd_s is now a Gutenberg-first theme! We merged in our pull request to convert all of our Flexible Content Blocks over to native Gutenberg blocks via ACF about a month ago and are looking forward to seeing how we can grow and expand the awesome functionality ACF provides.

There’s a lot going on here, so feel free to take a peek at our acf-gutenberg.php file to see how everything works together in the wd_s Github repo.

There, you can follow the breadcrumb trail to see some other magic we’re doing with our template files, template tags, and global block options like background elements. While there will always be improvements to be made, those will come in time as we use this new system more and more in real-world situations.

What have you built with the Advanced Custom Fields + Gutenberg integration and where can you see it going from here? Let us know in the comments below!

The post Integrating Advanced Custom Fields + Gutenberg Into wd_s appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2019/10/24/advanced-custom-fields-gutenberg-wd_s/feed/ 0 21285
WDS and Microsoft 365 Partner Together to Create a Custom AMP Experience https://webdevstudios.com/2019/08/20/custom-amp-experience/ https://webdevstudios.com/2019/08/20/custom-amp-experience/#respond Tue, 20 Aug 2019 16:00:56 +0000 https://webdevstudios.com/?p=21031 What Is AMP? In short, AMP is an HTML Framework, which helps pages load faster and look better than standard HTML pages. The framework prevents developers from shooting themselves in the foot by having strict coding standards and by requiring all pages to be validated before they can be “Amplified.” If you want to learn Read More WDS and Microsoft 365 Partner Together to Create a Custom AMP Experience

The post WDS and Microsoft 365 Partner Together to Create a Custom AMP Experience appeared first on WebDevStudios.

]]>
What Is AMP?

In short, AMP is an HTML Framework, which helps pages load faster and look better than standard HTML pages. The framework prevents developers from shooting themselves in the foot by having strict coding standards and by requiring all pages to be validated before they can be “Amplified.” If you want to learn more, check out a recent blog post, “AMP ⚡More Than Just Mobile Pages.”

Discovery and Scope

When our client, Microsoft, came to us last month, they had already rolled out AMP on another one of the web properties, Office Products, and were ready to get Microsoft 365 on AMP. The goal was to provide mobile users with a better experience when searching for Microsoft Office products.

We knew that we wanted to leverage the official AMP for WordPress plugin, and we’d need to customize templates to account for minor design adjustments on the blog post template. The stakeholders required custom pixel tracking, support for their custom videos, as well as a header and footer that closely matched their current design. Finally, this project would need to go live by mid-August.

Development

Knowing we only had two weeks of development and QA time, we got right to work. Looking at the options available in the AMP for WordPress plugin, we decided to leverage Reader Mode and customize the Classic Templates. It just so happened that we were busy writing blog posts about AMP and the AMP for WordPress plugin. Both Weston Ruter and Paul Bakaus from the Google AMP team had offered to peer review them and offered to point us in the right direction if we had questions about customizing templates.

Getting Started

The first thing we needed to do was customize the header and footer. While AMP for WordPress offers a hook for customizing the footer output, it doesn’t offer the same thing for the header—just a hook to inject things into the <head> of the page.

Our first run at this was through using the amp_post_template_file filter, which allows you to specify a different template file then what the plugin would use by default. While this worked, we soon pivoted to a much simpler and more streamlined solution: the /amp/ directory in our theme. Similar to other plugins which allow you to override and customize template files in your theme, AMP for WordPress gives you the ability to customize its various templates by adding template overrides to a top-level /amp/ directory in your theme.

So, instead of using filters to specify a brand new header and footer, we simply copied the header.php and footer.php files from the AMP for WordPress plugin into our theme’s /amp directory and customized them there.

The Single Post Template

Of course, a nice header and footer don’t mean much if you don’t also have a nice single post template. The out-of-the-box single template packaged with AMP for WordPress works really well and did most of the heavy lifting for us, but Microsoft 365 has some custom functionality that needed to be reworked to be AMP-compliant.

AddThis

Since we were using AddThis on the desktop version of the site, we needed to continue using AddThis on our AMP single post templates. Like a bunch of real sweethearts, the AMP team has made this an extremely easy process to undertake.

The first step, aside from having your AddThis widget ready, is to call the required JavaScript required for the service to work. It’s all spelled out super clearly in the AMP documentation, which tells you exactly which script is required. For us, we were also going to be using the `amp-audio` component (which we’ll look at in a bit), so our header script hook looks like this:

View the code on Gist.

Next, grab your publisher ID and widget ID from AddThis and drop this in place wherever you need to display it:

View the code on Gist.

Easy! We’ve now got fully functional and AMP-approved AddThis tools in place.

Audio Player

Aside from standard post content, we also needed to ensure that our post meta would transfer from the full version of the site to AMP. In this case, this comes in the form of an optional MP3 uploaded to each post. If the MP3 is present, then an audio player should display above the post content. In WordPress, this is fairly easy to do by using built-in shortcodes with our post meta passed in. In AMP, audio is just as easy—and even easier if you’ve already implemented something like AddThis.

Just like with AddThis, the AMP documentation has detailed information on how to implement the amp-audio component. You’ve already seen how we’re including scripts in the <head>, so we won’t cover that again. For implementation of the audio player itself, we simply needed to pass our post meta into the amp-audio component:

View the code on Gist.

This, combined with our header script, gives us a perfect audio player! You can see that we’ve got a fixed width of 840px on our player. This is because, at its largest, our content area is 840px wide. We’ve added some CSS to ensure this never expands past max-width: 100% so our player doesn’t break the viewport on mobile.

Analytics

You didn’t think we’d forget analytics, did you? AMP didn’t, either!

While there is a specific amp-analytics component, the specific analytics tool we’re using is embedded through a standard iframe. AMP is built to handle this, too. Using the documentation for amp-iframe, we were able to smoothly implement our analytics tracking… until we weren’t. More on that later on in the tricks and tips section of this post.

For the setup, you just need to include the required script as noted in the documentation. By this time, you’re an old pro having implemented AddThis and the Audio Player. You can include the script in the <head> like we saw in our previous examples, then include your amp-iframe with the necessary details in place:

View the code on Gist.

We included this snippet at the bottom of our /amp/footer.php file to ensure it was included on every post with a unique identifier (the post title) to meet the needs of the analytics tracker.

Tips and Tricks

amp-iframe

Earlier we talked about implementing amp-iframe into the site. This was a fairly painless process, but we did run into one speed bump along the way.

It turns out that when a post embeds a video or some other piece of content, which creates its own amp-iframe element, the AMP for WordPress plugin automatically includes the required amp-iframe script.

This created a problem for us on some posts but not all of them. Certain posts included video embeds in the content, and when this happened, our post would fail AMP validation. Why? Because, since we were already manually including the required amp-iframe script in our <head> and AMP for WordPress was requiring it again based on the existence of amp-iframe in the post content, the script was included twice and failing validation.

The solution came from one of AMP’s Head Developers, Mohammed Razzaq, on the AMP for WordPress plugin support forum.

To get around the issue, remove the manual call to the amp-iframe JavaScript in the <head>. Then, hook into the amp_post_template_data filter to check for the existence of the amp-iframe component script. If it hasn’t been loaded yet, tell AMP to load it. Otherwise, do nothing:

View the code on Gist.

Implementing this solved our duplicate script woes and helped all of our posts reach full AMP validation!

The /amp/ directory

This was mentioned earlier in the post when discussing the header and footer, but like many other plugins, AMP for WordPress makes it incredibly easy to modify default template parts.

While you can do this via hooks and filters, we prefer to use the directory method where you create a top-level /amp/ directory in your theme and modify the templates as you see fit. This helps keep everything compartmentalized in the /amp/ directory and keeps other theme files lean and trim.

To start modifying, simply copy the template you need from the AMP for WordPress /templates/ directory into your theme’s new /amp/ directory, and go wild. We wound up doing this for four template files: header.php, footer.php, meta-author.php, and single.php to make the necessary customizations for this project.

Yoast Integration

yoast dashboard with custom logo
Make sure you check this setting in Yoast

While validating the templates, we ran into a structured content error with the site logo. The structured data requirements are very strict and requires the logo to fit in a 60x600px rectangle and either be exactly 60px high (preferred) or exactly 600px wide. This led us on a wild goose chase.

At first, we swapped out our website logo in the WordPress Theme Customizer to match the 600x60px requirements and then tried to re-validate. When it failed, we scratched our heads a bit. We went through code bases for both the theme and the AMP for WordPress plugin and could not find any reason why this was happening. The AMP for WordPress plugin is supposed to pull in the logo used in the Theme Customizer.

Finally, we found a setting in Yoast, under Search Appearance, called Knowledge Graph and Schema.org. There’s an option to upload a logo, which ended up superseding the logo we used in the Theme Customizer. When we uploaded the 600x60px logo there, the structured content finally validated.

The Result

Microsoft 365 on AMP

The AMP project for Microsoft Office 365 was deployed on August 13, 2019, and now we wait for Google, Bing, and Twitter to pick up the AMP versions of the page. Our clients were pleased with how quickly we were able to turn around gorgeous article templates, while ensuring their existing media worked and making sure they would continue to have accurate insight into key visitor metrics.

If you’re looking for a long-term partner to help you with your AMP strategy and delivery, WebDevStudios is your solution. Check out our other blog posts around AMP, and if you’re ready to chat, reach out via the Contact page. ⚡

The post WDS and Microsoft 365 Partner Together to Create a Custom AMP Experience appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2019/08/20/custom-amp-experience/feed/ 0 21031
Breaking the Cycle of the Mean Developer https://webdevstudios.com/2019/05/28/mean-developer/ https://webdevstudios.com/2019/05/28/mean-developer/#comments Tue, 28 May 2019 16:00:59 +0000 https://webdevstudios.com/?p=20658 We’ve all done it before. Imagine this: you inherit code from some unknown, unseen website developer and you scoff at it as you begin to pore over it. You repeatedly face-palm as each new line of code brings another cry of, “Why did they do it like this?” You may even share the code with Read More Breaking the Cycle of the Mean Developer

The post Breaking the Cycle of the Mean Developer appeared first on WebDevStudios.

]]>
We’ve all done it before.

Imagine this: you inherit code from some unknown, unseen website developer and you scoff at it as you begin to pore over it. You repeatedly face-palm as each new line of code brings another cry of, “Why did they do it like this?” You may even share the code with your developer friends or co-workers and chuckle at its quality in comparison to your own or your team’s.

But, why do we do it? What’s the point of perpetuating the stereotype of the mean developer by ridiculing the code of another, regardless of whether or not they’re aware you’re doing so? Who does it benefit? Most importantly, how can we, as developers, stop being so critical, cynical, and rude and start being more mindful of our words and actions while working toward a better web?

For the sake of our argument, we’re going to refer to “bad code” as code that may be ugly to look at (poorly formatted), repetitive, not extensible, or that is lacking in performance. If code raises security concerns, then that’s another boat altogether and should be addressed with care, but still not with ridicule.

Recognizing the problem of the mean developer

This is the easy part. If you’re a developer, there’s about a 99.99% chance you’ve laughed or groaned at someone else’s code when you were asked to take it over. Inheriting headaches is never fun, and sometimes you truly do take over code that is poorly written or not future-proof. These headaches, though, aren’t helped by agonizing someone else’s code not being up to your standards. In fact, doing so will only make things worse.

When you take over a codebase from someone else, you should consider that not everybody is at the same level as you find yourself. You may have been developing websites for the past 15 years when you adopt the code from a developer who has only been at it for a couple of years. Is the code they’ve written really any less valid than what you would have written? Sure, it can probably be improved upon, but do we need to act as a gatekeeper with new developers?

Think back to when you first started. For me, it was working in Notepad and building sites from scratch with beautiful, beautiful tables. As I and the web developed, I was able to add new tools to my workbench. When I first learned about the ability to put all of your styles in a single stylesheet and remove the need for inline styles, my mind was blown.

Just because I got to that point at that very moment in my journey, though, doesn’t mean that someone who didn’t learn about it for another six months was any less a developer than I was. Perhaps they only built sites every so often and weren’t as entrenched in web development at the time. Nonetheless, they still did the work and got there at their own pace.

The next time you’re bequeathed code from another developer and want to laugh or complain about what they’ve written, think about your own journey first. Think about how you would have written the very same thing two, three, or five years ago, and then think about how you would write it today.

A photo image of WebDevStudios Lead Frontend Engineer, Corey Collins, in the flamingo pose (standing on one leg). Corey is the author of the blog post, "Breaking the Cycle of the Mean Developer."

How to deal with bad code

Just stop.

Take a step back.

Breathe in deep and let it back out (that last part is very important, please don’t forget to breathe out).

Then dive into the code.

You may be taking code over for any number of reasons. Maybe you’re forking a repo to build off of something else, or you’re on a project working with multiple vendors and need to integrate code from another developer/company into whatever it is you’re building. Perhaps you’re joining a new company and are taking over for someone who has since moved on.

The main thing to keep in mind is that nobody is writing what you consider to be bad code on purpose (probably). Developers are writing to the best extent of their knowledge at the time and could be dealing with any number of extraneous circumstances not made clear in the code.

How many times have you done anything in your life “good enough for now” because you were under a time crunch? One time, I royally messed up a pizza dough and it wound up tasting way more like a pretzel than a pizza. Still, it had cheese, sauce, and other toppings. It was technically edible—good enough for jazz, right?

While you may not be able to fix a bad pizza, you can fix bad code. Plus, if you’re working with the person who wrote the bad code, then you’ve got a wonderful teaching opportunity. If not? Well, then you can rest peacefully knowing that you’ve taken something and improved it with your good big brain. What a treat!

Dealing with bad code can be as much a learning experience for yourself as it can be for the developer who originally wrote the code. You have the unique ability to peek inside of someone else’s mind and try to parse what they were thinking when they wrote something. Maybe it looks wrong to you, but does it actually work? If so, isn’t it sort of neat that someone was able to accomplish something their own way with a working end result?

What’s important to remember is that bad code does not mean a bad coder wrote it. We’re always learning, growing, and trying new things. If your code from years ago looks the same as it does now, you’ve got a problem. So much changes and evolves in just a year that, as a developer, if you’re not constantly trying new things, then you’re going to find yourself falling behind.

Yes, maybe your code technically still does what it needs to do… but will the person ahead of you who has been experimenting and learning beyond your knowledge level see your code as “technically good” or as something on which to improve?

A photo image of WebDevStudios Senior Backend Engineer, Zach Owens, and Lead Frontend Engineer, Corey Collins. Corey is the author of the blog post, "Breaking the Cycle of the Mean Developer." In this image, Zach and Corey are standing, facing the camera, smiling, and have an arm around each other's shoulders.

How to stop being a mean developer

This might be the easiest thing to do with the biggest hurdle in front of it. It’s easy to be cynical and catty in your daily life, and those instincts are multiplied when you’re in a rush or have a lot on your plate. As much as it pains me to take off my own tinfoil hat from time to time, it’s important to remind yourself that everybody else isn’t out to get you.

You aren’t picking up someone’s bad code as a punishment or a cruel joke. You’re simply nudging forward the life cycle of developers, code, and the web.

When you adopt someone else’s code and the logic behind it puzzles you, stop and ask yourself why someone would write something in this way. More often than not, they just didn’t know of any other way. It could be way over-engineered or needlessly complex, but that doesn’t mean it’s actually wrong. If you can accomplish the same thing in fewer steps or with better performance, do it!

If you’re in the unique position of working with the person whose code you’re inheriting, ask that person why they wrote something a certain way. There may be more behind their code than simply not knowing any better. Maybe they, too, were jumping onto some other previously written code and needed to tailor their new code to the existing codebase.

If you’re unsure of any issues you may run into by beginning a code cleanup, reach out to your team or community. Assuming the code is safe to share with your group, try to get some insight into why something could have been written a certain way while also sharing your suggestions for cleaning it up. You may find that someone has an even better solution than your own allowing yourself to grow as a developer and someone else to grow as a teacher.

When it comes down to it, just take a moment to think about what you’re doing. It may feel good to laugh at something like a pile of bad code, but it’s not getting anybody closer to solving any of your problems. It’s a pointless exhibition of elitism and potential gatekeeper behavior.

The next time you want to deride another developer’s code or process because, “I wouldn’t have done it this way,” or “This doesn’t make any sense,” don’t. Instead, appreciate that you have the opportunity to see someone else’s process while also expanding your own mind to see that there is almost always way more than one way to accomplish something.

Above all else, though? Don’t be a jerk!

A photo image of WebDevStudios Lead Frontend Engineer, Corey Collins, sitting on a sofa with his eyes looking to his left and a disturbed look on his face, as someone else sitting next to him is wearing a horse head mask and looking at him, creepily. Corey is the author of the blog post, "Breaking the Cycle of the Mean Developer."

The post Breaking the Cycle of the Mean Developer appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2019/05/28/mean-developer/feed/ 3 20658
Five Reusable Code Snippets to Reduce Development Time https://webdevstudios.com/2019/01/08/reusable-code-snippets/ https://webdevstudios.com/2019/01/08/reusable-code-snippets/#respond Tue, 08 Jan 2019 17:00:29 +0000 https://webdevstudios.com/?p=19592 When was the last time you started a project from scratch? I mean literally from scratch—not using a framework, a parent/child theme, or any plugins. Maybe never? One could argue that as long as you’re using WordPress that you’re not necessarily creating anything from scratch since the CMS offers so much functionality out of the box already. What you Read More Five Reusable Code Snippets to Reduce Development Time

The post Five Reusable Code Snippets to Reduce Development Time appeared first on WebDevStudios.

]]>
When was the last time you started a project from scratch? I mean literally from scratch—not using a framework, a parent/child theme, or any plugins. Maybe never? One could argue that as long as you’re using WordPress that you’re not necessarily creating anything from scratch since the CMS offers so much functionality out of the box already.

What you do, though, is iterate on that functionality and build upon the tools provided to you or the tools you have built for yourself in the past. After all, if you’re doing work around the house and need to hammer some nails into the wall, you’re not going to head into your garage to carve the wood and forge the steel to make a new hammer every single time (unless you’re our very own builder and wood magician Will Schmierer). You’ll use the same hammer to do the same job until the hammer is no longer useful or you find a new tool with which to replace it.

Why then would you not develop a site in the same way? Granted, most projects are going to require distinct sets of functionality unique to the projects themselves but there are plenty of ways you can reuse code to save time so you can truly focus on providing the best possible work with the best possible turnaround. Some of these reusable code snippets might not be necessary for every project, and that’s okay. Maybe you only need to use them a few times a year, but whenever the need arises you find yourself searching online or through your old code to find something you know you’ve written at least once before.

In this post, I’m going to share some things that have made their way into wd_s because we, as developers, find ourselves using similar functionality over and over again. Maybe you’ll find one, some, or all of these snippets useful. Whatever the outcome, I hope that I can help to trigger some thoughts on when and where you can reuse functionality in your own processes to more efficiently complete your projects.

1. Social Network Links

Social networks, despite all the good and bad they put out into the world, are almost essential to have a digital life in this day and age. As such, there is rarely a website out there without links to the various social media accounts linked to the business or person attached to the site. In a WordPress install, there are several ways you could implement links to a set of social networks.

You could create a widget to manage the URLs, but what if you have many sidebars throughout your site and don’t want to deal with the tedium of manually replicating the same widget over and over again?

You could add URL fields to the Customizer and pull the data out into a template tag, but even then you’re limited by a finite number of fields in the Customizer. Perhaps, at launch, you only have Twitter and Facebook accounts, but six months down the road you spin up an Instagram account. Now, you’ve got to dive back into the code and go through the somewhat convoluted steps to add a new field to your Customizer settings.

You could even add the links to your social networks in a menu and then add a custom class to the menu items, like menu-icon-facebook, and then target that class (or set of classes, for all of your networks) in your CSS. Still, that requires an extra step and if you’re building a site for someone who may not be familiar with WordPress’ menu interface this could be confusing or frustrating.

So, what’s the solution? This is what I’ve found to be useful time and time again. First, it can be helpful to register a brand new menu location for your social networks:

View the code on Gist.

By registering a menu, you’re making it easy to reuse that menu anywhere you want throughout your site. You can add it as a widget via the built-in Custom Menu widget; you can create a custom template tag in your theme to display the menu attached to that particular menu location, and any number of countless things that can be done with a WordPress navigation menu. You’re already making life easier for yourself by relying on WordPress to do a bunch of work for you!

You don’t want to have to worry about doing any extra work when adding your menu items. You want to create the menu, add your links, and have your social icons displayed through some sort of magic. Well, I don’t have any actual magic for you but I do have a Sass snippet that will get the job done for you.

By targeting the menu and the href attribute values of the menu items, we can display the corresponding icon for each social network. Let’s take a look at that:

View the code on Gist.

First, you’re creating a $social-sites Sass list which holds the names of all of our social networks. Be mindful of this and don’t try to get cute with the names as they have to correspond directly to the URL you’re providing for your links.

Next, you’re targeting the links within your menu and looping through your $social-sites list to add an SVG as a background image. Your each loop is going to target your link’s href attribute and set the background image to match. This requires you to remember two things:

  1. As noted above, be sure to use the actual domain of the social network so your href targeting will work as expected.
  2. Remember to name your SVG files (or whatever other files you wish to use) to include the domain name. You can append or prepend a string (like icon-facebook.svg), but just be sure to make sure your background-image path matches your naming convention.

Now, wherever you use that menu throughout your site you should “automatically” see the icon displayed. You’ll want to do some other work to make sure the text also doesn’t display so that you’re seeing just the icon, or tweak the styles as you see fit if you do wish to display both the icon and the link text. You have the power!

2. Open Graph (OG) and Meta Tags

With social networks in mind, you’ll also want to make sure that any content shared from your site looks beautiful across every platform. There are plugins that will handle this for you, like Yoast SEO, but what if you don’t need a full SEO plugin or prefer to use a different solution for search engine optimization?

Fret not! OG and other essential meta tags can be a bit daunting at first, but with a recent update to wd_s we’ve tried to take some of the guesswork out of them. There are a lot of conditions that you could, and should, check for if you’re writing your own tags. You may want to serve up different sets of data for different post types or taxonomies, in which case you would need to modify the example snippet a bit to suit your needs.

Of course, if you’re using a plugin like Yoast, which will also provide you with all of the fancy-schmancy meta tags you need to produce beautiful Twitter and Facebook cards, then we’ll want to avoid messing with them. At WDS, we don’t tend to run into many clients who want to use an SEO plugin other than Yoast, so the snippet you’ll see below includes a check for that specific plugin:

View the code on Gist.

If Yoast is active, bail so that we don’t wind up with duplicate meta tags causing headaches and collisions. If you make this a part of your framework, you’ll want to be sure to either add in the checks for any plugins you may use to manipulate OG tags or simply remember to remove the function if you know that you’re going to be using a plugin to handle these tags. This also future-proofs your theme, if you’re doing work for a client. Should they launch their site without Yoast and then decide to add it six months down the line, you’ve got them covered. Your custom meta tag solution won’t interfere with their activation of the plugin, thanks to the conditional at the top of the function.

3. Archive Page Titles

You’re always going to have archive pages of some sort in WordPress, but for some reason, the titles of these pages are always a point of contention. Out of the box, WordPress creates a category archive page with a heading like “Category: Category Name.” Have you ever wanted to keep the prefix on that title? I certainly haven’t, and I don’t think we’ve had a single project in my (so far) seven years at WebDevStudios where a client wanted us to keep the prefix either.

If you’re working on a project for a client of your own, perhaps you never discussed this ahead of time. Since the archive pages are created dynamically, it may just be a passing note that the pages will retain the same look and feel as the rest of the site without much more discussion. However, more often than not, you’ll realize that everybody has an opinion on this after the fact even if they never stated their preference before.

Luckily, it’s pretty simple to remove the prefix from titles of these archive pages. So, instead of displaying “Category: Category Name” as the page title, you will instead display “Category Name.” Maybe you do want to add something before (or after) the base page title. Good news: you can! This snippet simply removes the prefix, but you can modify it to do any number of things to suit your needs from project to project. If nothing else, this is a handy snippet to keep on hand so you don’t have to Google “remove prefix from WordPress archive pages” every time you need to do this.

View the code on Gist.

4. Numeric Pagination

This isn’t a huge one, as WordPress provides an out-of-the-box way to display pagination throughout a site via paginate_links. So, what can we add to something already built into WordPress? We can make it easier to use and reuse in your templates. As you can see at the Codex link above, paginate_links offers a whole slew of options of which you can take advantage. You can customize the previous and next link text and how many page numbers are displayed in your pagination amongst others.

The issue with just using the core template tag is that anytime you use it, you need to set your own values, if you want to override the defaults provided by WordPress. We can get around this by creating our own template tag and invoking paginate_links with our own array of customizable options.

View the code on Gist.

In this snippet, we’re creating a template tag to power our paginated links. The function accepts an array, which means we can still customize the output of the links as if we were using paginate_links by itself, but we have the bonus of being able to include our own set of default values so you never have to worry about filling those in whenever you want to use this function. Then, if you do happen to have a spot on your site where you want to override your own custom defaults, you simply need to call the new template tag with the array of custom values passed in. As our function is, more or less, a wrapper for paginate_links, it accepts the same parameters for customization as seen in the Codex.

5. Post Headers and Footers

Nine times out of ten, the blog posts for your project are going to require some additional information displayed outside of title and content. We’re talking categories, tags, a posted-on date, and an author name. Once again, WordPress offers a number of ways to grab all of that information out of the box, but why toil around looking for the best way to display these extra details when you can just have it from the get-go? After all, am I going to need get_categorieswp_list_categories, get_the_category_list, wp_get_post_categories…? Stop the insanity!

Instead, let’s do this once and we can always tweak it on a per-project basis if need be, rather than starting with a blank canvas every single time. Let’s start at the top where we’ll want to display some important information: author and post date. With the following snippet, not only are we just getting the information we need, we’re also outputting it with some handy-dandy markup to make it even more usable.

View the code on Gist.

So now, you’ve digested the post title, author, and posted date. You’re ready to sit back and enjoy the contents of the post before you reach the end and look for some additional, related content and ready your nimble fingers to leave a friendly comment on the post (because you would never leave anything other than a friendly comment somewhere on the internet).

This snippet, just like the others in this post, can be modified to fit your needs. For us, we’re only going to try and display categories and tags on posts but you can adjust this for other post types or even rework the template tag on a deeper level to include custom taxonomies. First, we check to see if we’re in a post before checking for and displaying categories and tags. Then, if comments are open and the post isn’t protected, we’ll display the comments link. Finally, we’re displaying the edit post link so you can quickly jump back into edit mode if you need to do so.

View the code on Gist.

Quick Wrap-Up

Now that you’ve got a handful of useful snippets to speed up your next project, what other ways can you think of to smartly reuse code from project to project smartly, and what are you going to do with all of that newfound spare time? Let us know in the comments below!

The post Five Reusable Code Snippets to Reduce Development Time appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2019/01/08/reusable-code-snippets/feed/ 0 19592
Filtering ACF Content Blocks with WordPress Hooks & Filters https://webdevstudios.com/2018/11/29/filtering-acf-content-blocks-with-wordpress-hooks-filters/ https://webdevstudios.com/2018/11/29/filtering-acf-content-blocks-with-wordpress-hooks-filters/#respond Thu, 29 Nov 2018 17:00:22 +0000 https://webdevstudios.com/?p=19433 Here at WebDevStudios, we do quite a bit with Flexible Content Blocks in Advanced Custom Fields (ACF). If you aren’t familiar with the plugin, ACF allows for the creation of a multitude of custom meta field types using a graphical user interface (GUI) in the WordPress Dashboard. You can do almost anything with these fields—from simple Read More Filtering ACF Content Blocks with WordPress Hooks & Filters

The post Filtering ACF Content Blocks with WordPress Hooks & Filters appeared first on WebDevStudios.

]]>
Here at WebDevStudios, we do quite a bit with Flexible Content Blocks in Advanced Custom Fields (ACF). If you aren’t familiar with the plugin, ACF allows for the creation of a multitude of custom meta field types using a graphical user interface (GUI) in the WordPress Dashboard. You can do almost anything with these fields—from simple text and URL inputs to searching for posts and pages and building image galleries.

ACF allows you to power your site with robust customization options, which you can use to create and manage dynamic pages. Instead of being locked into a set of page templates where the functionality and layout are tied directly to the theme’s files, building pages with ACF Flexible Content Blocks puts the power of customization into your hands as a site manager and editor. You can add, remove, and rearrange blocks as needed and have full control over the content within each of those blocks.

Sometimes, though, simply customizing the content within those blocks isn’t enough. Sure, it’s nice enough to be able to edit the title of a block or select a different set of Featured Posts to display. But, what if you don’t want to have to get that far into the weeds with customizing your pages and posts? What if you would rather set a category on a page or post and rely on the content blocks to figure out in which category your page resides and update the block content dynamically?

We recently discovered a use-case for such a situation and were able to find some fun and interesting ways to extend our standard ACF Flexible Content Blocks. Instead of requiring anybody to manually edit a set of content blocks already added to a page, we were able to add functionality into our blocks that look for the page’s category. Then, by the magic of wizards (or WordPress, I guess), we can filter the output of the block drastically cutting the time it takes to update an entire page of content.

So, what did we do and how can you use it, too? Let’s dig in and find out!

Our Block Code

Let’s start with a common case and a block which would be super handy to filter by a post’s category: Call To Action. This block ships with wd_s out of the box, so we’ll start first by looking at the markup driving it:

View the code on Gist.

You may be asking yourself (or me, though I promise I can’t hear you), “Why would I need to dynamically filter that? Can’t I just edit the block’s contents?” Well, yes, you could just edit the block’s contents and be on your way. But, what if you use that same Call To Action on, say, a dozen pages which all share the same category? Suddenly, you realize you want to change the title of the Call To Action if that one specific category is set. Rather than having to edit a dozen individual posts, you could utilize a filter in your theme’s code to handle that work. That means less time editing posts and more time sitting back, sipping coffee and admiring a job well done.

How do you get there, though? First, let’s modify the block to be able to accept filters:

View the code on Gist.

This starts off similarly to the initial block but there are some crucial changes in place. First, you’re creating a $default_args array immediately after you grab the block’s values. This stores the values you are saving to the block, like the title or button URL when you edit the page.

Directly after you set those items in the new $default_args array, you’re creating a second array called $block_args which merges the $default_args array with any potential array passed in via a WordPress filter. This means that if you never use the filter, nothing will ever change with regard to how this block works on the frontend. You’ll still edit the block as you normally would and see the expected updates when you save the page.

However, if you hook into _s_cta_block_args (as you’ll see later on), you can pass in your own custom values for all of the information you set in our $default_args array earlier in the snippet.

The final set of changes comes in how you output your data. Instead of simply calling the individual variables, like $title, you need to look inside of your $block_args array. Remember, even if you’re not passing in any filters for the current condition, you’re still creating a brand new array called $block_args which holds all of your data. So, instead of outputting $title you now need to output $block_args['title']. This is a small and subtle but pivotal change, otherwise the filtering won’t work once you get to that point.

Applying Our Filters

Now for the real magic. It’s all well and good to have the ability to filter the content, but how do you actually go about hooking in and filtering anything? With the magic of a WordPress filter, you can hook into the aforementioned _s_cta_block_args filter and run wild. You will need to be sure to test the conditions for these filters in various scenarios. If you simply hook into this filter without any conditional statement within it, the contents of the block will be altered everywhere it is used throughout the site.

View the code on Gist.

So, it’s important to know when and why you need to filter your content. In this case, you’re going to check to see if the block is being used on a page or post which is set in a specific category. If it is not, you simply return your $block_args array. This means that you don’t alter anything and the block functions as it normally would. If you do find yourself on a page with that category set, though, the fun and excitement can begin.

You’ll need to pay attention to the array keys and be sure that they match what was set in your block’s template file, otherwise, you won’t see your filtered changes reflected on the frontend. In the example above, you’re filtering almost everything–the block’s title, the button URL and text, and you’re adding a CSS class so you can target this block with special styles sometime down the road.

Wrapping Up

And that’s it! You now have the ability to filter the content in a block without having to actually edit a page. This could be a massive time-saver if you realize that you need to change the URL of a button or link in a block that you’ve added to dozens of pages all which exist within the same category. Plus, once you’ve done it once it becomes second-nature to be able to add this same ability to your other existing blocks.

What other uses do you think you could come up with for filtering blocks this way?

The post Filtering ACF Content Blocks with WordPress Hooks & Filters appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2018/11/29/filtering-acf-content-blocks-with-wordpress-hooks-filters/feed/ 0 19433
The Journey to 1.0 — WDS Blocks and WordPress Gutenberg https://webdevstudios.com/2018/05/22/wds-blocks-wordpress-gutenberg/ https://webdevstudios.com/2018/05/22/wds-blocks-wordpress-gutenberg/#comments Tue, 22 May 2018 16:00:02 +0000 https://webdevstudios.com/?p=18432 WordPress made a big leap into the world of modern web development with its announcement of Gutenberg last year—reimagining what WordPress is and can be by providing a new interface for creating content built partially on the React.js platform. Since it will most likely be rolled into Core sometime mid to late 2018, WebDevStudios (WDS) Read More The Journey to 1.0 — WDS Blocks and WordPress Gutenberg

The post The Journey to 1.0 — WDS Blocks and WordPress Gutenberg appeared first on WebDevStudios.

]]>
WordPress made a big leap into the world of modern web development with its announcement of Gutenberg last year—reimagining what WordPress is and can be by providing a new interface for creating content built partially on the React.js platform. Since it will most likely be rolled into Core sometime mid to late 2018, WebDevStudios (WDS) is looking toward the future. Enter WDS Blocks.

As of May 2018, WordPress runs ~30.7% of the internet. For better or worse, it’s going to be hard to ignore the impact Gutenberg will have on the web when it officially launches. The new feature is being teased to the public now, and though it’s nowhere near a stable final release, its adoption rate is growing exponentially and WDS needed a game plan to ensure we’re not behind the curve.

Pre-Planning

In August 2017, during one of our weekly leadership calls, the topic of Gutenberg was brought up. Everyone thought the project was a bit premature to start building on top of. We discussed the possible future implications but weren’t ready to give the idea of building our own custom Gutenberg blocks any serious attention. Gutenberg had just barely been announced, and like many suggested features, its future was uncertain. So it was tabled for several months.

Four months later, WDS named Greg Rickaby to the position of Director of Engineering, and by this time, Gutenberg had become the biggest topic in the WordPress space—there was no ignoring it.

Greg spoke with Cristina Holt, our Director of Project Management, and the initial thoughts were to approach Gutenberg just like a client project and pitch it to our CEO, Brad Williams, and put the full weight of our talented developers behind the project.

“First we needed to train our engineers and project managers,” explains Greg. “Second, we had to come up with a development plan and schedule, then finally put together a project team. It took a few conversations with leadership, but Brad and Lisa eventually agreed to let us move forward with the ‘WDS Gutenberg Project.’”

Once the project was approved, Cristina and Greg assembled a team which would be led by Lead Frontend Engineer, Corey Collins, and Lead Backend Engineer, Kellen Mace. The engineering team was rounded out by Jo Murgel, Eric Fuller, and Will Schmierer.

Our first release was to replicate or replace components such as Heroes, Cards, and Calls-To-Action. These are components that are commonly used by our clients on typical website projects and are already included in our starter theme, wd_s. We call these “Global Content Blocks” and they’re powered by Advanced Custom Fields’ “Flexible Content” feature.

The Training Plan

Zac Gordon has been leading the charge on educating WordPress developers since Matt Mullenweg so famously said, “Learn JavaScript, deeply.” We purchased Zac’s Gutenberg course (now called WordPress Block Editor) over at https://javascriptforwp.com/. After all, the best way to learn anything is to immerse yourself.

Each of our engineers was scheduled some time to take the course. Once they completed their training, they could get spun up on WDS Blocks.

The Development Plan

While training, Kellen Mace had read about Ahmad Awais’s Create Guten Block on Github, which bills itself as a zero-configuration toolkit for spinning up Gutenberg blocks. He proposed using it to provide the foundation for our WDS Blocks project. Finding this toolkit was honestly a relief, as the thought of scaffolding the project and configuring Webpack from scratch wasn’t something any of us really wanted to do.

We also needed to provide greater advanced settings for each block including the ability to change the background decoration (image, color, video), add some visual flair (animate.css classNames), and a few other options to provide greater control to users beyond what is inherently available from WordPress out of the box.

Our blocks needed to provide a simple and clean backend experience with a fairly generic theme-friendly frontend render. For release 1.0 we ended up working toward a hero, call to action area, recent posts grid, manual-select related posts grid, a dual-column layout, and a gist embed. Since then we’d added several updates to these blocks and a users grid block with room to grow going forward.

The Result

Like most stories, the journey is far more interesting than the end result. We learned a lot about what Gutenberg can and can’t do, why they chose React.js, and why they added an abstraction layer.

Utilizing Gutenberg’s Inspector Control tools, we were able to create a set of Background, Text, and Other Options that we could easily replicate across all of our blocks. We even wrote about it so we could share what we learned and how we were able to keep our code DRY in order for our options to be as easy as possible to implement in new blocks.

Despite the insistence from WordPress themselves that aMultiSelect component wasn’t necessary, Issue #1044, we found the use case for such a component important. So we built one as a part of our recent posts and users grid blocks.

During the rest of our development, we found ourselves needing to reuse bits and pieces throughout our blocks. In addition to creating seven new blocks (plus a default block to copy from), we also created 10 new reusable components! These cover Options noted above, post search, and MultiSelect amongst others. Being able to create standalone components, and control their output at the component level, helps us keep a clean and consistent codebase across all of our blocks.

Based on the way Gutenberg is built and how it renders markup to post_content there was a problem with creating dynamic or non-static blocks that needed to be worked out. More on that at the WDS Blog: WordPress Gutenberg — Arrays, Attributes, and the Fundamental Flaw – WebDevStudios.

Initially, our plan was to render all of our blocks via PHP because we ran into issues when updating the markup for blocks. For instance, when rendering in JSX, if you were to add a className to your block container, you would receive a popup in the post editor informing you that your block was no longer valid, and the new className would not be present on the front-end. After some digging, we were able to realize that Gutenberg’s deprecated function was exactly what we needed. This allows for you to make changes to your block, to have those updates visible on both the backend and frontend of your site and to avoid the “invalid markup” popup after changing your block’s markup. You can read more about Deprecated Blocks in the Gutenberg Handbook.

Finally, WordPress provides a feature for styling both the front and backend render. Before Gutenberg existed, you’d have a simple text-based WYSIWYG editor with no real indication of how the content might look on the front end. Appending theme styles to a WordPress Gutenberg Block has never been easier, with its shared styles allowing for a user experience which more closely resembles that of the frontend.

The Future

This is just the beginning. Every release of Gutenberg unveils changes in functionality, bug fixes and deprecated features forcing us to keep up with testing and look for additional functionality that can improve the user experience.

We plan to use WDS Blocks as a starting point for new website projects, providing many of the common blocks that our clients will likely need, then add to those any project-specific blocks.

We’ve opened the repo to the public and encourage everyone to get involved with the project. We welcome your help as we work to build out a library of powerful and useful blocks that take full advantage of WordPress’ new editing experience.

The post The Journey to 1.0 — WDS Blocks and WordPress Gutenberg appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2018/05/22/wds-blocks-wordpress-gutenberg/feed/ 1 18432
Creating a Global Options Component in Gutenberg https://webdevstudios.com/2018/04/12/creating-a-global-options-component-in-gutenberg/ https://webdevstudios.com/2018/04/12/creating-a-global-options-component-in-gutenberg/#respond Thu, 12 Apr 2018 16:00:40 +0000 https://webdevstudios.com/?p=18285 At WebDevStudios (WDS), we’ve seen many iterations of page builders and page builder-esque tools over the years. I think it’s safe to say that the experimentation began with CMB2 and led us down an exciting path that included a handful of full-fledged page builders and our own custom-built page builder before we finally came to rely Read More Creating a Global Options Component in Gutenberg

The post Creating a Global Options Component in Gutenberg appeared first on WebDevStudios.

]]>
At WebDevStudios (WDS), we’ve seen many iterations of page builders and page builder-esque tools over the years. I think it’s safe to say that the experimentation began with CMB2 and led us down an exciting path that included a handful of full-fledged page builders and our own custom-built page builder before we finally came to rely on Advanced Custom Fields (ACF) as a way to allow clients the freedom to edit, arrange, and customize their pages and posts. While ACF isn’t a page builder per se, its robust customization has given us the ability to present our clients with a similar level of customization found in strict page builders. Now… enter Gutenberg.

Here’s what the CEO of our company, Brad Williams, recently tweeted about it, “WordPress Gutenberg is not a page builder.”

While not a full-fledged page builder, Gutenberg does allow for the type of customization we have been building via ACF for several years. It certainly changes how that customization occurs, and part of our directive here at WDS has been to take what we have built in ACF and transfer it to Gutenberg. So, what is the first stop on the ACF-to-Gutenberg brain train? It’s converting our set of globally-used block options.

Part of what we include with all of our default ACF blocks is a panel of options to allow for some major visual customizations. These options include the usage of a background image, video, or color, customizing the font color, adding animation options and any custom CSS classes that a user may need to further tweak their block once it hits the frontend. As important as it was for us to make sure these options are available to use on all of our Gutenberg blocks, it was also important for us to ensure:

  • The options are easy to include for developers
  • The options exist in one central location to keep our code DRY
  • The options work visually in a Gutenberg block the same way they work currently in an ACF block

Getting Started

My first step was to get completely overwhelmed. Digging into reusable Gutenberg components is no small task. After running through Zac Gordon’s Gutenberg Development course, I was comfortable building blocks and even components in the Inspector Controls panel, but this took on a whole new level. We needed conditional fields and, as stated earlier, a way to keep this code as DRY as possible to avoid simple mistakes from being made when attempting to include the Background Options on a new block.

Our options panel is broken down into separate parts, so it made sense to tackle these one at a time rather than trying to do all of the things in one sitting. We’ve broken down the various options into:

  • Background Options
  • Text Options
  • Other Options

For the sake of this post, we’ll be focusing on Background Options. Before we get into the code, take a look at the file structure for our component.
View the code on Gist.

Let’s start by looking at what lives in our outlier JavaScript files, because their contents will be what makes the rest of our component work.

First, we have attributes.js. Like any regular Gutenberg block, our component needs attributes to save when its values are edited. We broke this out into an individual file because it would help keep our index.js file clean, and it makes it easier to import our attributes into our blocks later on. Inside of our attributes.js file we have:
View the code on Gist.

What we’re doing here is setting our default attribute types and then exporting the entire set of attributes for use later on. Now if we ever need to update our Background Options attributes, we won’t have to edit them across all of our various blocks. We’ll just edit them once here and let them trickle down into our blocks wherever they are being used.

Next up is our classes.js file. Neither classes.js, inline-styles.js, or video.js are required by Gutenberg; these are files that will drive markup for functionality for us later on when we begin building our blocks. In classes.js, we’re checking to see which Background Type is selected (image, video, color, or none) and adding a matching class to our block:
View the code on Gist.

In inline-styles.js, we’re doing a similar thing as in classes.js . We’re checking to see which Background Type has been selected and then pulling in its value as an inline style. Specifically, this checks to see if we are using a background color or a background image and sets that value as an inline style on our parent container if either is found:
View the code on Gist.

Finally, our video.js file outputs the video selected when using the “video” Background Type. Since we can’t set a video to be a background element of a container the same way we can with a color or image, we have to output the video markup in the container and then position everything via CSS. Inside of our video.js file is where we’ll keep the markup for our video output:
View the code on Gist.

With that out of the way, it’s time to start building the functionality of our component. The first thing we need to do in our index.js file is import any core WordPress and Gutenberg dependencies we’ll be using. These will vary slightly from component to component depending on what types of fields you’ll be using, but for us, we wound up with:
View the code on Gist.

In order to keep our main file clean, as noted above, we broke out as many things as possible into individual files. Next, we have to import them into the index.js file and export them so we can use them later on in our individual blocks. That last part will make sense once we get into creating a block. For now, let’s just assume you trust me, we import and export our internal dependencies like so:
View the code on Gist.

Now, we can actually get into the nitty-gritty of building out the functionality for our Background Options component. First, we need to create a new function and export it so we can use it in our blocks:
View the code on Gist.

Note that we’re passing in props —this is important because we’re going to be using these to check, get, and set attributes throughout this function. Before we get into any of that, though, let’s set some variables for our various event listeners so we have something to hook into when we want to change the background color, background image, or anything else we’ll be customizing in this function:
View the code on Gist.

Now, it’s time for the fun stuff! The first piece of the puzzle we’ll be building out is our Background Image Selector. Let’s kick this off:
View the code on Gist.

Before we do anything, let’s check to see which Background Type has been selected. If the user has selected the “video” Background Type, then there’s no point in displaying the Background Image Selector.
View the code on Gist.

Now that we know for sure whether or not we’re actually selecting an image, we can build out some further functionality. With this next bit of code, we want to check to see if we have a background image already set. If we do, then we don’t need to display the MediaUpload component. But, if we’re starting fresh and want to select an image, then we definitely need that component handy. This utilizes the core Gutenberg MediaUpload component that we imported way at the top of this file:
View the code on Gist.

But, what if we already have an image? In that case, we want to display the image we’ve already uploaded as well as a way to remove it and replace it with a new image:
View the code on Gist.

Since this comes after our first conditional check, we don’t need to check whether or not an image is already set. If we’ve made it this far in our function, then we know we already have an image saved and are safe to try and output the saved image.

Next, let’s prepare our Video Background Selector. The code here is going to look somewhat similar to the Image Selector we just built, but of course, there are little touches here and there that make it its own special thing. It begins just the same way by setting a const:
View the code on Gist.

Just as we did with the image, let’s check which Background Type has been selected before proceeding:
View the code on Gist.

Now, we need to see if we have a video saved already. This is pretty darn identical to our Image Selector above, except it’s specifying “video” as the value for “type” in the MediaUpload component:
View the code on Gist.

We want our users to know which video they’ve uploaded to a particular block. So if a video is already set, we’re going to display a non-playing version of it in our component:
View the code on Gist.

Finally, we want to be able to select a background color if the “color” Background Type is selected. Just like with the two previous examples, let’s start things by setting a const for our Color Selector:
View the code on Gist.

This particular selector is going to be a lot more streamlined, as we don’t have to worry about including an uploader or outputting anything visually in our component that doesn’t already come from core Gutenberg. First things first, let’s check our background type:
View the code on Gist.

And if we know that we’re looking to set a background color, then we know that we need to display Gutenberg’s PanelColor and ColorPalette components:
View the code on Gist.

We’re almost there! At this point, we’ve created the core functionality of all three of our Background Types: image, video, and color. But, how do we actually tell our component which one of these options we want to use? And how do we actually get any of this stuff to show up in our Inspector Controls panel?

To start, we’re going to veer from what we’ve been doing so far and simply return rather than setting a const. At this point, we’re actually beginning to output the contents of our component rather than building its individual parts. First, we need to start a PanelBody container:
View the code on Gist.

Inside of PanelBody , we want to have unique rows. One will house the Background Type select while the other will house the output for whichever value we have selected. Each of these will live inside of a core Gutenberg PanelRow component. For our Background Type selector, we’ll need to build a selector dropdown and, lucky for us, we can use another core Gutenberg component! We also want this particular option to be visible regardless of the selected Background Type because we want to give our users the ability to change Background Type at any time.
View the code on Gist.

Gutenberg really comes through and makes this easy for us. We’re simply creating a select dropdown and specifying the labels and values for each of our options. Remember all of the conditionals we set earlier in our function where we checked for backgroundType? This SelectControl is what sets the backgroundType value and allows those conditionals to work. Make sure your value for each of these match up to what you’re going to be checking for elsewhere in your functions.

Lastly, we need a way to set our background image, video, or color. Remember when we created our const variables above and did all of the work of setting our image, video, and color values? The reason we set those as const variables the way we did is so we could create a cleaner output in this return. Just below the PanelRow we created for the Background Type selector, create another PanelRow to output our settings:
View the code on Gist.

You might be yelling at me right now that this won’t work—that we’re simply outputting all three of these individual Selectors with no rhyme or reason. Untrue! If you recall, when we set our const variables above, we also checked to see if the selected Background Type matched the type of Selector we were about to display. Inside of all of those const variables, we’re already checking to see which Background Type is set and either bailing if we don’t have a match or displaying the settings if we do. Checking inside of the const lets us keep a very clean and streamlined render at the end of our function.

To see the full version of this file, check out the Gist here!

If you’re still with me… good! We just have a few more things to do before we can see this sucker when editing a block. So far, we’ve built the functionality out but have yet to add it to a block. We’ll do that next. I won’t go over how to build the entire block, because that’s a blog post for another day. If you want to see the end product of what we have in our Default Block as it stands now, you can view that here.

For our purposes, we’ll assume you have the block built already and are looking to add a Background Options panel to your block.

First, we need to make sure you’re importing InspectorControls from Gutenberg core in addition to whatever other blocks you’re importing:
View the code on Gist.

Remember back in our Background Options index.js file when we imported our attributes.js, classes.js, inline-styles.js, and video.js files then immediately exported them? We did that so we could easily and cleanly import all of our necessary Background Options pieces in one line:
View the code on Gist.

With that one line, we’re gaining access to the entire BackgroundOptions function we built as well as all of the goodies that we’re using to make our magic happen. Now, we need to actually begin including those things in our blocks. The first step is to include our attributes. Like I’ve said before, we strive to keep our code as DRY as possible and this was no exception. We didn’t want our developers to have to copy and paste a complete set of attributes every single time they created a new block, and we especially didn’t want to have to update a bunch of different files if our attributes changed at any point in the future.

The beautiful thing here is that with another sweet, single line we can import all of our attributes:
View the code on Gist.

Next, we need to actually output our options panel. This happens inside of the edit function of our Gutenberg block and, again, by utilizing exports and imports we’ve made the process super easy. First, we check to see if our block is in focus and, if it is, we add our InspectorControls panels:
View the code on Gist.

Again, with that single line, we’re pulling in all of our BackgroundOptions functionality and passing in our props so we’ll have access to them in our component. This is really what makes the whole thing work. Without those few lines, we won’t have anything displayed in our InspectorControls panel.

Finally, we need to output some markup so our block will listen for our Background Options and behave accordingly. For the next section, just know that you will have to output the same markup in both your edit and save functions to ensure your block functions properly and displays your options on both the frontend and backend.

We’re using a section tag to wrap our block, and because we want to add a class and potentially inline styles based on our Background Options choices, we’ll need to tell our markup to do just that:
View the code on Gist.

With those in place, we’ll now be able to see the background image or background color set for our block when using the “image” or “color” Background Type. But, what if we’ve selected “video” and have uploaded a beautiful MP4 to display in the background? Easy! We just need to display our video output using the import from the top of our block.
View the code on Gist.

To see the full version of this file, check out the Gist here.

And that’s it!

I know, I know… “that’s it.” There’s a lot to digest here. A lot of this may have been overwhelming to read (it was overwhelming to write, too!), but I would encourage you to do exactly what I did when I started building this component. Do it wrong, get confused, and then start over. When I first started trying to build the Background Options component, I did it by starting with some code Jeffrey de Wit wrote. I had a hard time understanding what he was doing or why it was working. So, I broke everything down to its simplest form. Instead of going all out and building the entire Background Options panel, I started with just the Background Type select dropdown so that I could understand how values were passed between files and functions and just how everything worked at its core.

Once I had an understanding of that one component, I was able to piece everything else together in my brain to make it work. Along the way, I had some help from Eric Fuller, a noted JavaScript guru around these parts, who helped me break everything out into individual files and keep things as smartly-written as possible.

After the Background Options were taken care of, building the Text Options and Other Options panels were a bit of a breeze. They are far less complex than dealing all that came with building the Background Options panel, so they came together much more easily. As always, you can follow along with the progress of our WDS Blocks plugin and check out how we’re handling our other global components in our Github repo.

What brave, new worlds have you come across when getting to know Gutenberg? What have you built that seemed crazy at first, but wound up being completely worth the confusion and frustration that comes with trying to do something outside of your comfort zone? And, what are you looking forward to in Gutenberg as its inclusion in WordPress core gets closer and closer? Let us know in the comments below.

The post Creating a Global Options Component in Gutenberg appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2018/04/12/creating-a-global-options-component-in-gutenberg/feed/ 0 18285