Recently.

Making Bootstrap Components Dynamic with EE

Making dynamic content with ExpressionEngine is one of my favorite things to do. I've used Bootstrap for years and I've always been really fond of all the components it offers. 

I'll be starting out by making a series of posts focusing on those certain components and how to make them more usable and powerful with EE.

So, let's start off by making Bootstrap's Accordion component a fluid field type.

Accordion - Bootstrap v5.0 - link to the documentation.

I'll start this by copying the snippet from the documentation and pasting it where I keep the fluid fields. I keep these fields in an includes folder to reuse for other templates if needed. Furthermore, I know there is a template partials folder created for this type of thing, but I've been creating an includes folder for years. It's just a bit of a habit, and maybe I'll change ways in the future.

I've called the include file .content-blocks where I format all the fluid fields.

After I've copied the html, I'll delete the other examples since I only really need one to do the job. ExpressionEngine will do the rest.

Next, I'll create the fieldtype using a grid, so I can repeat the accordion rows. I'll just name it accordion, while giving the grid fields a title and description.

After the fields are created, we'll start by declaring the fluid field name and the grid field we just created around the code snippet for the accordion component.

Since I named my fluid field content_blocks, I will have to include this before the accordion field with an opening and closed tag and place the Bootstrap Accordion snippet in between so that EE Grid field can repeat a new Accordion row.

I'll place the {content:title} for the Accordion heading and {content:desc} for the Accordion content that expands. 

Just to note, I gave the Accordion description field a shorthand name of desc as this is just a form of habit and I prefer to keep shorthand names as short as possible.

Now there are still some things we need to add to the snippet, but we can go ahead and create some Accordion rows to test how it works. Make sure you have the Accordion, Grid fieldtype added to the Fluid fieldtype. So with what I've created, I need to add Accordion to my Content Blocks field.

You can do this by going to Fields on the left-hand navigation under Developer. Search for your Fluid fieldtype and add the Grid field to the Fluid field.

Now let's add some test fields to the blog post I'm creating. I'm actually using my blog and this post as the full example for creating this component for the blog. 

ExpressionEngine formats your fluid field fields nicely and makes it really easy to rearrange and organize all your custom content. 

Now that I have my example created, we can already notice some issues with how it looks and the interactivity of the Accordion. First, both Accordion rows show as if they are already collapsed by the selected color and indicator arrows on the right of each row. If I click on either one of the rows, both rows will expand or collapse, so we need to take a look at the html snippet to correct this.

If we take a look at the HTML snippet, everything within this row is getting repeated by the Grid field that we created. All the attributes and IDs are the same as well. Which is why all rows will react when one is clicked on. We need to find a way to differentiate the rows so that they are all unique to each other. We can use row_id to help us make each of these rows unique.

ExpressionEngine - Row ID

The {row_id} will output the database ID for the individual grid fields we create. Which we can use this to our advantage by combining this with our HTML IDs and data attributes. This is to ensure that everything in each accordion row is different from the next one created. Even if it's another Accordion under another piece of text on that same page. Here is how we will structure it.

We'll add {content:row_id} between the {content} tags at the end of each ID and attribute, so each Accordion row will have their own unique data. The ID for the whole entire Accordion that corresponds to data-bs-parent attribute is a little bit trickier to get the same outcome as the Accordion's main ID has to remain outside those {content} tags as we are only repeating one Accordion row or if you look at the class that is being repeated, class="accordion-item". So let's look at targeting the fluid field itself.

ExpressionEngine - Fluid Fieldtype

Using the {count} variable should work well with this, so we will declare the name of our Fluid field with the variable like so: {content_blocks:count}. Let's add this to the end of both our main Accordion ID and data-bs-parent (As pictured above).

Now if we inspect element in our browser, we can see that each Accordion (I created two examples) matches with the main Accordion ID and the data-bs-parent as it should and both examples seem to be working individually on their own when they are selected. Below are the examples. 

Great! Now we can style these and tailor them to our theme or anything else really. I believe there are several ways to make this process easier or more organized, but this was a first attempt at tackling this particular Bootstrap component. It just goes to show how powerful ExpressionEngine is and how creative you can get when creating custom content. This is why I've preferred using ExpressionEngine the most over the years.

Anyway, I hope this provides insight to others out there. More to come soon!

12/27/2022 |

ExpressionEngine Dynamic Meta Tags

When I worked for Bulldog Creative Services, there were some sites that I would be tasked with creating that focused on blog content and while WordPress is big on being a blog platform we sometimes went with ExpressionEngine depending on the client and what they needed. When it came to dealing with health content and site's that attorneys used, we went with ExpressionEngine because of how easily we could boost SEO and performance and also because of how secure ExpressionEngine is. 

We had a project for a local Attorney's firm in Huntington, WV to recreate a site that sometimes produced 1-3 blog posts a week. The blog posts were written by several attorneys of the firm where you could filter by author, category and search. We decided ExpressionEngine would be best used for this site. This was when ExpressionEngine version 5 was current.

The firm had a company that revised the content, provided images and directed where we would add meta titles, descriptions, image alt tags, etc. This allowed myself to get kind of creative with blog posts and how I would use them in the future.

For sharing data, I needed to target the Open Graph tags in my main layout for each page and blog posts. The {layout} tag works perfect for this.

ExpressionEngine - Template Layouts

First, I'll start out by creating the channel fields I need and assigning them to the Blog channel. I've added a field for an Alternate Share Image, Alternate Title, Meta Description and Keywords. The purpose of creating an alternate sharing image and title is to allow the author more flexibility in customizing how it appears when the blog post is shared. Otherwise, the post would use the hard coded og:image and blog post title.

Also, I like to keep the shorthand names of fields as short as possible to keep my templates as dry as possible. It's just a form of habit, but these are particularly long. 

This might seem strange to some, but there have been several instances where I've needed to shorten a blog title or description so important parts appear in a shared post on Facebook for example. I've also had authors request to use different images for the shared post. Also, odd sizes of images sometimes cause the size of the shared post to look odd. Overall, it helps the author achieve exactly how they want their post to look like on social media sites. 

For the sake of making this a little more organized, I'll create a new tab in the Channel Layouts for Meta Description.

I'll then take the template that I'm using for the single blog post and start setting these channel fields I've created under the channel field declaration (As pictured above).

We can use {layout:set name=""} to create variables that will correspond to our main layout template where we include the meta tags.

{layout:set name="image"}{if pages_alternate_image !=""}{feat_image}{if:else}{pages_alternate_image}{/if}{/layout:set}

I've used some conditionals between the opening and closing layout tags to indicate if a page image is not chosen, then it will use the featured image that I've created a field for. Also, if an alternate page title is not chosen, then the blog title will be used in the social media post.

name="image", name="title", name="description" and name="keywords" are the variables I'll use in the <head> of my main layout template.

Finally, I'll go ahead and declare these meta tags in my .layout template.

From the .layout, I can target those variables in my metadata like so: {if layout:keywords != ''}<meta name="keywords" content="{layout:keywords}">{/if}.

I've included conditionals in the layout because for some, if there is nothing entered in that particular field then I'd rather there be nothing at all OR something in place for it rather than others. I know the above image looks a little unorganized, but when I do work on certain things, part of the template always seems to change based on what I'm building. Either way, this works very well for customizing your own meta data for each page or post. 

Lastly, it is good to test and preview your post to see how it appears, so I've always used Facebook's Debugger tool to see how everything looks before sharing. Of course, previewing the link on Facebook's actual site is possible. This is a neat little tool to use as it will inform you of open graph tags that you might be missing. Just paste the link and hit debug and Facebook will crawl that post's meta information.

Sharing Debugger - Facebook

12/27/2022 |

Mars and Pleiades

I recently got a new wide angle lens for my camera that I tested out while I was up visiting family for the holidays in Philippi, West Virginia. The good thing about this region is the lack of light pollution, which made for beautiful photos. One of my best friends who is an extremely talented photographer taught me how to star hop a few months back, and it's become extremely helpful when looking up and immediately noticing where certain celestial objects are in the night sky. Yeah, I know it's pretty easy to pull out your phone and track these with an app, but it's fun to know where some things are and hop to another. I always remember the ones pictured below now.

If you look up at the night sky and immediately notice Orion's belt, you can go north a bit until you see a bright red object which is Aldebaran, a red giant star. Going north even more, you will notice the Pleiades Cluster above it.

12/04/2022 |