Half-Elf on Tech

Thoughts From a Professional Lesbian

Author: Ipstenu (Mika Epstein)

  • OpenGraph Images and Taxonomies

    OpenGraph Images and Taxonomies

    As I worked my way through optimizing the SEO for my Dead Lesbians, I hit a recommendation that I found difficult to handle. It was presented simply. Add an open graph image to the page.

    The problem was the page was a category page (a custom taxonomy).

    Easy: Yoast’s OG Image

    The easiest solution if you’re using Yoast SEO is just to make a custom image and upload it. Go to the taxonomy page, edit it, go to the Yoast section, click on the sharing icon, and you’ll see what needs to be added.

    If you want to automatically handle the open graph image with Yoast SEO, it’s filterable.

    function halfelf_wpseo_opengraph_image( $image ) { 
    	return $image; 
    }; 
    add_filter( 'wpseo_opengraph_image', 'halfelf_wpseo_opengraph_image', 10, 1 );
    

    This means if you have a specific image for a category if the image doesn’t have a post thumbnail, you could do something like this:

    function halfelf_wpseo_opengraph_image( $image ) { 
    	global $post;
    
    	if ( !has_post_thumbnail() ) {
    		if( in_category( 'foo', $post->ID ) ) {
    			$image = get_stylesheet_directory_uri().'/images/cat_foo.png';
    		} elseif( in_category( 'bar', $post->ID ) ) {
    			$image = get_stylesheet_directory_uri().'/images/cat_bar.png';
    		}
    	}
    	return $image;
    }
    

    That’s really bad code, by the way. There are smarter ways than hard coding, especially since you can do some pretty nice stuff with primary categories in Yoast SEO. I would probably have it grab the primary category for the post, force the image, check to make sure the image exists, and have a fallback (just in case someone else added a new category).

    The problem is that the filter doesn’t work on categories and taxonomies because they don’t have the filter set. Posts and pages are fine. Not categories.

    Easy: Adding via wp_head

    Adding in an open graph image via the wp_head action is similarly possible.

    add_action('wp_head', 'halfelf_opengraph_image', 5);
    function halfelf_opengraph_image( ) {
    	echo '<meta property="og:image" content="http://example.com/og_image.png"/>';
    }
    

    This is extendable and you can customize it to be as simple as my example or as complex as pulling a specific image per category or featured image, depending on your theme.

    Not Easy: Reality

    Besides the fact that I can’t use Yoast’s filter for categories, I had a bigger problem. The way I designed my theme, most of my taxonomies had a custom image picked. The images are all SVGs. And you know what doesn’t work on OG images? Yeah, SVGs. Good news was that I had a copy of all the images as a PNG as well, so I was able to use the second method to create default images using the PNG.

    More bad news? I didn’t actually know how to grab the taxonomy ID. While WordPress has a handy function is_tax(), I couldn’t use a global like $post to grab a $tax->ID. Thankfully I could use get_queried_object_id() to set my term ID like this:

    add_action('wp_head', 'lez_opengraph_image', 5);
    function lez_opengraph_image( ) {
    
    	// If it's not a taxonomy, die.
    	if ( !is_tax() ) {
    		return;
    	}
    
    	$term_id = get_queried_object_id();
    	$icon = get_term_meta( $term_id, 'lez_termsmeta_icon', true );
    	$iconpath = get_stylesheet_directory().'/images/png/'.$icon.'.png';
    	if ( empty($icon) || !file_exists( $iconpath ) ) {
    		$icon = 'square';
    	}
    
    	echo '<meta property="og:image" content="'.get_stylesheet_directory_uri().'/images/png/'.$icon.'.png" />';
    
    }
    

    Obviously I know where I’m storing the images. You’ll want to change that for yourself. I went with a fallback image of “square” in case there wasn’t one available, just because I hate having nothing show. Also here I only wanted the custom taxonomies to have this image, not the regular categories and tags.

  • Custom Meta, Keywords, and Taxonomies

    Custom Meta, Keywords, and Taxonomies

    As I continue using OnPage, I was able to make some pretty fast gains. All the work I did with Yoast and CPTs immediately saw me picking up higher rankings for some of my keywords. That meant I had successfully optimized the pages for shows and characters.

    The hard work happened next. See one of the terms I wanted to rank for was “dead lesbians” and if you look at that right now, we’re not in sight. We own the domain deadlesbians.com which sends you to https://lezwatchtv.com/cliches/dead/ but how do we amp that up?

    I don’t want to have to customize every single taxonomy and, initially, I had the default titles set: %%term_title%% Archives %%page%% %%sep%% %%sitename%%

    This translated into “Dead Archives – LezWatchTV” and that’s pretty good but it could be better. Since I’m talking about character clichés here (characters have clichés and shows have tropes you see), the title could be better as “Cliché Archive: Dead Queers” and that takes two changes. First I rename the taxonomy to “Dead Queers” and second I changed my default titles to be prettier. But that made me think of a couple things.

    Meta Titles: Rated Orange

    If you look at the above screenshot, it shows that I only have an ‘orange’ for a good title. After some fiddling, I determined that Character Cliché Archives for %%term_title%% %%page%% %%sep%% %%sitename%% gave me green results, though not a full bar. The reason here is that the length of what you’re using matters. Meta descriptions should be around 160 characters (Yoast’s crew have seen 135-250) but meta titles are a little odder.

    Before I get too far into that, I have to explain that there is one annoying thing about keywords when it comes to taxonomies. If you have the premium version of Yoast SEO, then you can pick multiple keywords for posts and pages. You can’t do it for taxonomies. That means even though my page is named “Dead Queers” I was going to have to manually give it a custom keyword and handcraft the title.

    I do not recommend this in the long run for everything. And in fact, this is the only place I plan on doing this. I manually made the keyword ‘dead lesbians’ and worked from there. Doing that gave me a different sort of direction, since I got the following message:

    The SEO title contains the focus keyword, but it does not appear at the beginning; try and move it to the beginning.

    Of course. That made perfect sense and I changed the title to start like this: %%term_title%% Character Cliché Archives

    Once I had done all that, I went back and changed the focus keyword to “The big list of dead lesbians.” Now this is not a keyword. But it lets me do this: %%focuskw%% A collection of all queer female TV show characters who have fallen prey to the cliché of %%term_title%%.

    Originally I wanted to make a custom term meta and variable (like I made for %%actors%% and %%shows%%) but I couldn’t get it to output. Since the focus keyword is there to help me optimize things, I don’t see anything wrong with this but …

    Warning: the variable %%focuskw%% cannot be used in this template. See the help center for more info.

    That’s what happened when I tried to set that on the Taxonomies page. And I can see why. It’s frustrating though, since I really do want it just not to show if I don’t have it set.

    In the end, I had to make that page the one with a super custom meta.

    The big list of dead lesbians. A collection of all queer female TV show characters who have fallen prey to the cliché of %%term_title%%.

    We’ll just have to see how that goes. I would much rather make it as flexible as possible, and lot of this would be easier if I was using a specific page and not a custom taxonomy listing. But there are still some limitations when you’re working differently.

  • Genericons Neue

    Genericons Neue

    In 2013 I made a silly little plugin called Genericon’d which let you include Genericons on your site in a theme independent way, complete with shortcodes and flexibility for other plugins and themes that might be using it. In 2016, Generico became Genericons Neue.

    The changes were small but huge:

    1. SVG instead of font icons
    2. No more social icons

    The problem I faced was equally small but huge:

    1. How to seamlessly transition from font icons to SVGs
    2. How to handle social!!?!?!

    Thankfully Automattic actually did the hardest work for me, with Social Logos. I can’t design logos. I didn’t want to abandon people. So for me, to be able to just include a second library in the plugin was a fast and easy fix.

    The long and drawn out one was how to make the plugin magically transition. It took me a month, fiddling with it off and on, but as of version 4.0, Genericon’d defaults to using modern SVGs instead of fonts and combines the Genericon Neue icon pack as well as Social Logos to ensure your old code keeps working. If SVGs won’t work for your site, you can either use classic Genericons or the legacy font packs.

    Genericon'd default settings

    Yeah, I gave everyone ‘options’ while still making default decisions. For the most part, no one needs the old legacy stuff unless they’re supporting IE, so this should work right out of the box for everyone, new and upgrades. My only ‘beef’ is that Social Logos doesn’t have a release strategy, so I’m going to have to randomly check for updates.

    A lot of the work I did to figure this out was just testing variations. I knew that by default I wanted everyone to use the minified, super fast SVG sprites, and by default you do. There are hidden options that would let you use the slower images, but I didn’t build out that interface because of the annoying complexity with setting up “if you have Genericons Neue, make sure you don’t have Genericons Classic!” That was a surprisingly large amount of ifs and elses to make it logically flow. I wanted to have it magically flip things over for you, but in the end I went with an alert if the plugin is active and you haven’t selected things.

    You can also make your load even lighter by not including the social icons, but one thing that’s nice about SVGs over Font Icons is that if you’re not using them, there’s no extra load on the site.

  • Yoast Custom Meta with CPTs

    Yoast Custom Meta with CPTs

    Remember Monday when I was learning about how I was ignorant of SEO from OnPage?

    Right so here were the odd keyword notes it told me I needed to take care of and I had no idea what was going on. I mean, I looked at this and stared:

    • Add the keyword kima greggs in the meta title
    • Add the keyword kima greggs in the meta description
    • Add the keyword kima greggs to the content of your page
    • Add the keyword kima greggs in the headlines (<h1> to <h6>)
    • Add images and include the keyword kima greggs in the image’s ALT tag

    Then I did what every intelligent person does when faced with an unknown to-do. I read directions.

    The title tag defines the title and is displayed as the page name on the browser tab. The title is very important for search results. It is the heading used to display the search result and is crucial for the ranking.

    Now I actually knew, from having gone through every single tab in Yoast SEO, that titles and metas are handled from the plugin (Yoast > Titles & Meta > Post Types) and, by default, they’re set to be this: %%title%% %%page%% %%sep%% %%sitename%%

    Which translates to: “Pagetitle Number — Sitename”

    Or in the case of Kima, it’s “Kima Greggs — LezWatchTV” (since I never have any numbered pages for those).

    Cool, right? So it was there. Done. I also knew that the name was in the headlines. It wasn’t (and isn’t) in the content of the page, but I’ll accept that SEO hit since contextually it doesn’t work for what I’m writing. Similarly the image thing I handled by having the one image uploaded to the custom post type be the character photo with an alt tag and title of the character name.

    You see how I’m cheating.

    That left me with the meta description and a new question. You see, what I wanted the description to be would be “Kima Greggs, character on the following TV shows: [list of shows]” and what I didn’t want to do was manually type that for 1000 characters. Who would, right? Again, I knew Yoast had a way to customize that!

    Titles and Meta Descriptions for Yoast SEO

    You can see in the above screenshot I already changed the title to remove %%page%% since I know the pages will never be paginated. But the “Meta description template” I needed to address. First is the easy part. I want to document that the character is on a TV show. Fine: %%title%% is a character on a TV show and for TV shows, I could do %%title%% is a TV show and that worked.

    Of course, I wanted to add what stations a TV show was on, which meant I needed to use %%ct_<custom-tax-name>%% which lists the post’s custom taxonomies, comma separated. Except it didn’t seem to pick up things for my custom post types. Turns out this is a bug.

    When I added this: %%title%% is a TV Show on %%ct_lez_tags%% %%sep%% %%excerpt_only%%

    It displayed this: <meta name="description" content="Adventure Time is a TV Show on Cartoon Network &ndash; Adventure Time, c&#039;mon grab your friends. We&#039;ll go to very distant lands."/>

    That was the easy stuff. When I got to characters, it became a lot messier because of how data was stored. To do the basics I looked at what my custom fields were and came up with this:

    %%title%% is a %%ct_lez_sexuality%% %%cf_lezchars_type%% character played by %%cf_lezchars_actor%% on %%cf_lezchars_show%% %%sep%% %%excerpt%%

    Now that should have turned into “Jane is a Lesbian guest character played by Anonymous on Fake Show…” but what actually happened was “Jane is a Lesbian guest character played by Array on Array…”

    I knew why. Those two values are arrays. Which meant I had to come up with some new code.

    function lez_retrieve_actors_replacement( ) {
    	if ( !is_array (get_post_meta( get_the_ID(), 'lezchars_actor', true)) ) {
    		$actors = array( get_post_meta( get_the_ID(), 'lezchars_actor', true) );
    	} else {
    		$actors = get_post_meta( get_the_ID(), 'lezchars_actor', true);
    	}
    	return implode(", ", $actors);
    }
    
    function lez_register_yoast_extra_replacements() {
    	wpseo_register_var_replacement( '%%actors%%', 'lez_retrieve_actors_replacement', 'basic', 'A list of actors who played the character, separated by commas.' );
    }
    
    add_action( 'wpseo_register_extra_replacements', 'lez_register_yoast_extra_replacements' );
    

    What this does is creates a new template variable called %%actors%% and that lists the actors with their names separated by commas (yes, some people have multiple actors, have you even heard of US soaps?). The one for shows is more complicated since it’s a post type referencing another post type (shows and characters are post types), but it’s the same general concept.

    In the end I went with this: %%title%% is a %%ct_lez_gender%% %%ct_lez_sexuality%% %%cf_lezchars_type%% character played by %%actors%% on %%shows%% %%sep%% Clichés: %%ct_lez_cliches%%

    It crams a lot of information into a small place, but it’s also all the important stuff.

  • OnPage is On Fleek

    OnPage is On Fleek

    I’ve gotten back into using Yoast SEO (I like to say, I don’t always use SEO plugins, but when I do I use Yoast), and I noticed they’d added integration with OnPage.org. Of course I did remember this being added to the plugin in general, having chatted about it with Yoast and his crew, but at the time it really didn’t seem like anything I needed.

    Flash forward, and it’s 2016 and while I certainly can do all the things it takes to set up a site and make it’s SEO sing, a person can always learn more. So I set up an OnPage account and went to town.

    Actually I stared at it.

    You know how people say the WordPress dashboard can be overwhelming when you first look at it? Yeah, so was this. There were a lot of options. A lot of options. And a lot were sales things. Then there were a hundred pages of ‘metrics’ which I confess I didn’t understand what it fully meant. While I was still capable of churning out page after page of valuable content, and having context be my SEO queen, some of the nuances of what made pages ‘good’ to search engines was clearly being lost to me.

    Like I said, a person can always learn more, so after feeling dejected at myself, I decided to sit and study up. How was I going to master all this and understand how to make my site better and the content more search engine friendly? I knew once I got people to the site, the content would be useful, but getting them there was the nature of advertising (something difficult to target when no one aims ads for lesbians) and word of mouth.

    Thankfully OnPage has a tool Navigator, and once I started using it everything became clear. It walked me through the basics of setting up my site. It detected I used WordPress, it directed me to install an SEO plugin (Yoast of course) and then gave me step by step tasks to get those simple, basic wins.

    The first 18 tasks were things I’d already done, like hooking up Google Analytics, signing up for Google and Bing Webmasters, submitting my sitemaps, etc etc.

    OnPage Navigator makes me feel successful

    And then I hit the section about Keyword Pages.

    Create Keyword Pages

    That confused me since I knew the page that the keyword “kima greggs” should point to is https://lezwatchtv.com/characters/kima-greggs/ (pretty obvious when you see it, right?). I clicked on the link to complete the task and was surprised.

    Define a subpage that should be ranked for the keyword kima greggs:

    The bottom part of the page was a list of pages on my site, and none of them was the right URL. Oh dear. I entered it in manually and hit save. That presented me with new tasks:

    • Add the keyword kima greggs in the meta title
    • Add the keyword kima greggs in the meta description
    • Add the keyword kima greggs to the content of your page
    • Add the keyword kima greggs in the headlines (<h1> to <h6>)

    And then there were a lot more which were pretty easy but those… Well those led me down a path that will be continued later.

    The lesson to take here is that if you’re trying to figure out how to optimize SEO past the easy basics, OnPage can teach you about how you’re doing it wrong. It can teach you how to do it right. And eventually you can optimize things with the conscious understanding of why the code does what it does.

  • WordCamp US – LGBT+Allies Tribe Meetup

    WordCamp US – LGBT+Allies Tribe Meetup

    Thanks to the undying energy of Tracy Levesque and the dollars from many donators (including DreamHost), there will be an LGBT+Allies meetup on Friday night at WordCamp US. Yes, NEXT Friday. So if you don’t have plans, or if you just want some big gay friendly hang time, we’re inviting everyone to come hang out with diverse WordPressers at Philly’s most welcoming gay bar.

    You don’t have to be gay to come, but you have to be gay friendly.

    WordPress is welcoming to people of all cultures, beliefs, and sexualities. In celebration of our community, we decided to have an unofficial (non WordCamp sanctioned) meetup of the LGBT WordPressers and their straight allies. The celebration will be during WordCamp US at Stir Lounge, Philly’s most welcoming gay bar.

    We’ll have most of the place to ourselves with delicious food from The Khyber Pass Pub and an open bar.

    This event is made possible by our generous sponsors!

    YIKES, Inc.DreamHostWPEnginertCampCornershop CreativeAutomattic1SEO.com

    Bring your rainbow pins and your smiles.

    Personally, I think now, more than ever, it’s important to know where your tribe is and that we’ve got your back.

    You can get a ticket (for a whopping $0) at lgbtwp.ticketleap.com

    hero