Half-Elf on Tech

Thoughts From a Professional Lesbian

Category: How To

  • AMP It Up

    AMP It Up

    We’ve all heard about how Google wants to make mobile pages faster. The Accelerated Mobile Pages (AMP) Project is there to deliver and process a pared down version of a webpage, prioritizing speed. Since speed is important to your SEO, and I’m on a bit of an SEO kick, you bet it was next on my to-do list.

    I admit, Joost talked about this at his WordCamp US talk this year, and among my notes was this:

    Add AMP – not set it and forget it

    This is so, so true.

    The AMP Plugin

    First its like all things WordPress, you install the plugin AMP by Automattic and activate it. That does the easy work. Of course then you have to customize the hell out of it to make it look right. Still, out of the box the plugin adds a /amp/ so if you go to https://halfelf.org/2016/amp-it-up/amp/ then you’ll see my AMPlified pages. If you’re using Multisite, you may need to re-save your permalinks for the URL to work.

    There are some big warnings about this though.

    1) No analytics tracking
    2) You don’t get to design your AMP page
    3) It doesn’t work on the front page or pages or cpts

    Don’t worry! We can fix all that!

    Analytics

    If you’re using Monster Insights for Analytics, supposedly they added in some code to make tracking work, but I was unable to find it in the code or documentation. More than likely it’s in their Pro version. I don’t use that plugin simply because I found it easier to use a 28 line mu-plugin for my network and I don’t need to see my stats all the time. I used the AMP WP recommended method and put it in the same mu-plugin as I have my regular analytics.

    Design

    This is a little messy. Design is a very complicated word. If you just want to change the colors, you can do this via Appearance > AMP. Whaaaat!? That’s right, it lets you change the header color and font color right there. Super simple. If, though, you want to make your CSS tweaks directly to change that light blue header to navy, perhaps, you can follow the AMP WP directions for CSS additions and have this:

    add_action( 'amp_post_template_css', 'halfelf_amp_css' );
    function halfelf_amp_css( $amp_template ) { 
    	?>
    	.amp-wp-header {
    		background-color: #013659;
    	}
        <?php
    }
    

    I strongly recommend making few changes. Oh, color of course, but don’t go and make a 1 meg CSS file. The point of AMP is to load faster, after all!

    There’s a whole second level of design that I’ll get into later. It needs its own post.

    AMP your CPTS

    Right now you can only do it via code. The AMP WP directions for CPTs state they may come up with a better way, but for now you do this:

    add_action( 'amp_init', 'my_amp_add_this_cpt' );
    function my_amp_add_chars_cpt() {
        add_post_type_support( 'post_type_this', AMP_QUERY_VAR );
    }
    

    It’s pretty direct, and I added this in the bottom of my existing CPT code.

  • 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.

  • 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.

  • Managing User Permissions

    Managing User Permissions

    When it’s just you writing on your site, WordPress user management is incredibly basic. You have one user, you, and you do all the things. If you’re a little neurotic, you have one user who is an editor to write all your posts, and one who is an admin to do the admin things, and you religiously log in as the editor.

    But when you have a site with multiple authors, how do you handle them and their permissions? And what do you do when they leave?

    Lowest Common Denominator

    The most important thing to remember with any CMS or tool is to give users the lowest possible permissions. The people who are admins can do anything so they should be restricted to just the people whom you’ve discussed responsible administration, how to handle things, and who the ultimate top technical boss is. The Roles and Capabilities of WordPress can be very daunting, but the summary is very important:

    • Super Admin – somebody with access to the site network administration features and all other features
    • Administrator – somebody who has access to all the administration features within a single site.
    • Editor – somebody who can publish and manage posts including the posts of other users.
    • Author – somebody who can publish and manage their own posts.
    • Contributor – somebody who can write and manage their own posts but cannot publish them.
    • Subscriber – somebody who can only manage their profile.

    The Administrative

    I strongly recommend limiting your Admin accounts to less than 5. Most people don’t need to be an admin. In fact, the only annoying thing an admin is needed for would be adding new users. Everything else that they can do is, properly, administrative and requires some technical knowhow. You don’t want your copy editor updating a plugin that breaks a site, after all.

    Editors are like your moderators. They can approve posts, edit them, handle comments, and more. They cannot install and upgrade code, however, which is good. Admins (should) have server access, after all, not Editors. If you think of it that way, you may go less crazy.

    The Writers

    Your post writers come in two flavors: Authors and Contributors.

    The difference here is minimal but important. A Contributor cannot publish posts, and more importantly they cannot edit posts once published. That makes Contributor a good role for guest posters, or irregulars. If you need to review and approve every post before it’s live, this is the role for your writers. On the other hand, an Author should be someone you trust won’t go back and make naughty changes to posts after they’re approved and published.

    The biggest ‘flaw’ in Contributors is that they cannot upload files. This can be annoying, I know. If you need more robust tools for your writers, services like CoSchedule and plugins like Edit Flow may be up your alley.

    The Departed

    I don’t mean dead. What happens when your writer quits? You don’t want to delete their posts (probably) but you do want to balance their access with your security. The simplest solution is to make them a Subscriber. This means they can just read and leave comments on your site and nothing more. Their posts will still be attributed to them, but they cannot be edited.

    Of course, it the departure is less than amicable, another solution is to make them a Subscriber, but then change their email and password. If you use Gmail or GSuites, a super quick email fix is to create an alias like blogadmin+username@gmail.com for your users. For example, if the removed user’s login ID is johnsmith then I would create the email blogmaster+johnsmith@example.com and use that to own the ID. This prevents johnsmith from being able to log in and change his password again.

    For cPanel you’ll need to use forwarders and for Plesk you need aliases. Both require setting them up on the server side. Sorry.

    Custom User Roles

    I say this with a heavy heart. Most sites need to stay away from this. The basic five roles will suffice for most situations, and you should really try them for a while before dismissing. Adding in new users roles in WordPress can end with no one having permission to do anything. If you use custom roles, please be very careful and make sure you know how to restore basic user permissions in a pinch.

  • Hiya: Bye-a Spammers!

    Hiya: Bye-a Spammers!

    Do you get calls from scammers and telemarketers?

    Trick question! We all do!

    I stopped getting so many recently, thanks to Hiya. The claim?

    Hiya identifies the calls you want to pick up and automatically blocks the ones you want to avoid.

    And guess what? As of iOS 10.1 it sure does. I installed it after a day when I had eight scammer credit card calls in a row. In November, a day happened when I got a series of robocalls, and I didn’t answer any of them. My phone flashed, said it had a call, and then it went away, like a hangup. Curious, I popped into my call log to see who’d butt dialed me and saw Hiya flagged the number as a scammer.

    They were right. They’ve been nothing but right since I installed it and configured it, and I’ve been unbothered by crazy phone calls.

    Setting up the app is onerous, I’ll warn you. On an iPhone, after I installed Hiya, I had to go in to Settings -> Phone -> Call Blocking & Identification. There I had an option for Hiya to allow the app to block calls and provide caller ID. And once I toggled that on, it took minutes for my phone to sync everything up but … Once it was done, the app worked exactly as expected.

    The bother went away.

    Now for the dark side. Hiya needs access to your contacts. Their privacy policy isn’t fully clear on what they do with it, but they do say they take the numbers in your contacts to build a whitelist. After all, people you add to your contacts aren’t likely to be spammers. But they also claim not to use your information, sell it, or market to your contacts. They also don’t sell to 3rd parties.

    As a California resident, I can write and request (once a year) for a list of everyone they gave my information to, so I may do that later, but they appear to be on the up and up. They’re FTC governed, though given that the drama with all this started because they’re doing fuck all at stopping spammers, your milage may vary.

    Me? I’m kicking scammers to the curb.