Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: plugins

  • Prettier Search Queries

    Prettier Search Queries

    By default, when you search on a WordPress site, your search URL has an /?s= parameter. Back in the old days of WordPress, we all had URLs like /?p=123 where 123 was the page ID. With the advent of Pretty Permalinks, we moved to pretty URLs like /2016/prettier-search-queries/ and everyone was happier.

    What about search?

    As it happens, the WP Rewrite API actually has a search base of … search. If you go to your Settings > Permalinks page, you won’t see it there, and yet on every site if you go to https://halfelf.org/search/apache you’ll actually get that nice, pretty path.

    Because of that, you could get away with adding this to your .htaccess file in order to get those pretty URLs.

    RewriteCond %{QUERY_STRING} s=(.*)
    RewriteRule ^$ /search/%1? [R,L]
    

    You can also use a plugin like Mark Jaquith’s Nice Search.

    Those methods work for nearly all sites.

    But you know me. I’m not ‘all’ sites.

    Extra Paramater Headache

    I had a different problem. Because my site had specialized data, it had extra search parameters. I was intentionally limiting my search to specific post type. This meant my URLs looked like this: /?s=rookie+blue&post_type[]=post_type_shows

    When I translated that to use the pretty search, well …/search/rookie+blue&post_type[]=post_type_shows just didn’t work.

    This is for a pretty obvious reason when you study the URLs. The first one has ?s=... and then later an &, while the second only has the & in there. If I changed the URL to this, it worked: /search/rookie+blue/?post_type[]=post_type_shows

    The reason for this was due to how parameters work in URLs. They have to start with ? at the beginning. All additional parameters are added with ?param=value after that.

    Semi Pretty Search Permalinks

    To me, the nicest URLs would be `/search/rookie+blue/section/shows/’. The reality is that people will search shows and characters and I wasn’t quite sure how I wanted to handle that. Did I want them to be sections separated by plus signs, or extra ‘folders’ or what? In the end, I decided that for now it was okay to just make these prettier.

    Taking Mark’s code as my start point, I came up with this:

    function pretty_permalink_search_redirect() {
    	// grab rewrite globals (tag prefixes, etc)
    	// https://codex.wordpress.org/Class_Reference/WP_Rewrite
    	global $wp_rewrite;
    
    	// if we can't get rewrites or permalinks, we're probably not using pretty permalinks
    	if ( !isset( $wp_rewrite ) || !is_object( $wp_rewrite ) || !$wp_rewrite->using_permalinks() )
    		return;
    
    	// Set Search Base - default is 'search'
    	$search_base = $wp_rewrite->search_base;
    
    	if ( is_search() && !is_admin() && strpos( $_SERVER['REQUEST_URI'], "/{$search_base}/" ) === false ) {
    
    		// Get Post Types
    		$query_post_types = get_query_var('post_type');
    		if ( is_null($query_post_types) || empty($query_post_types) || !array($query_post_types) ) {
    			$query_post_types = array( 'post_type_characters', 'post_type_shows' );
    		}
    
    		$query_post_type_url = '/?';
    		foreach ( $query_post_types as $value ) {
    			$query_post_type_url .= '&post_type[]=' . $value ;
    		}
    
    		wp_redirect(
    			home_url( "/{$search_base}/"
    			. urlencode( get_query_var( 's' ) )
    			. urldecode( $query_post_type_url )
    			) );
    		exit();
    	}
    }
    add_action( 'template_redirect', 'pretty_permalink_search_redirect' );
    

    And that actually does work exactly as I want it to.

  • Damn You, Autocorrect!

    Damn You, Autocorrect!

    After the seventh time I shouted “stop autocorrecting cmb2 fields!” at my site, I knew I had to do something.

    When you run a website where you enter a lot of people’s names, Autocorrect is a curse more than a blessing. Of course I want it on my post content, but when I get to the field where I enter someone’s name, for crying out loud, some names like Nuñez just don’t meet a spell check. And don’t get me started on my friend’s names or my own. I’ve lost track of the number of times I ended up as “Mike.”

    This issue used to only be on phones and tablets. Then Apple introduced autocorrect to their MacOS, which resulted in a lot of tweets followed up by “Damn you, Autocorrect!”

    HTML Attributes

    If you’ve got a form and you want to tell autocorrect to go away, the code looks like this:

    <input autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" />
    

    For the most part, this will work. You don’t need all of them all of the time, but in my case I was adding names and “Debbie van Houten” was one problem and “Dr. el Farad” was another. I wanted it to just shut up and let me type the name as their parents intended, no matter what. I went whole hog.

    But as I mentioned, I use CMB2 and I needed to stop my site from autocorrecting CMB2 fields. It was time for some code.

    CMB2 Custom HTML Attributes

    This one is so straightforward I was delighted. When you create a new field, you can set arbitrary attributes.

    // Field: Actor Name
    $cmb_characters->add_field( array(
    	'name'				=> 'Actor Name',
    	'desc'				=> 'Include years (in parens) for multiple actors',
    	'id'				=> $prefix . 'actor',
    	'type'				=> 'text',
    	'repeatable'		=> 'true',
    	'attributes'		=> array(
    		'autocomplete'		=> 'off',
    		'autocorrect'		=> 'off',
    		'autocapitalize'	=> 'off',
    		'spellcheck'		=> 'false',
    	),
    ) );
    

    That was all I needed to do in order to get autocorrect to duck itself. Now I was free to write however weird a name I needed without worrying that autocorrect wanted to call me Mike. Again.

    Thanks, autocorrect. Thanks a lot.

  • 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 SEO: Selective Stopwords

    Yoast SEO: Selective Stopwords

    Stopwords are those small words that should be removed from URLs. You know like ‘a’ and ‘and’ or ‘or’ and so on and so forth. They make for ungainly and long URLs and really you should remove them.

    If you happen to use Yoast SEO for WordPress, and you want to disable stopwords, there’s a simple way about that. Go to SEO -> Advanced and disable the feature for stopwords.

    Disable stop-word cleanup, but why?

    If you want to kill it with fire and prevent everyone on your site from being able to activate them ever, you can toss this into an MU plugin.

    add_filter( 'wpseo_stopwords', '__return_empty_array' );
    remove_action( 'get_sample_permalink', 'wpseo_remove_stopwords_sample_permalink' );
    

    The first filter makes the stopwords kick back nothing, and the remove action stops the process from running. You probably only need the second one, but better safe than sorry, I always say.

    But … what if you want stop words removed, but you don’t want them removed on certain custom post types? Welcome to my world! I wanted to remove them from two post types only.

    Enter my frankencode:

    <?php
    
    /*
    Plugin Name: Yoast SEO Customizations
    Description: Some tweaks I have for Yoast SEO
    Version: 2.0
    */
    
    // Unless we're on a post or a post editing related page, shut up
    global $pagenow;
    
    $pagenow_array = array( 'post.php', 'edit.php', 'post-new.php' );
    if ( !in_array( $pagenow , $pagenow_array ) ) {
    	return;
    }
    
    // Since we are, we need to know exactly what we're on and this is a hassle.
    global $typenow;
    
    // when editing pages, $typenow isn't set until later!
    if ( empty($typenow) ) {
        // try to pick it up from the query string
        if (!empty($_GET['post'])) {
            $post = get_post($_GET['post']);
            $typenow = $post->post_type;
        }
        // try to pick it up from the query string
        elseif ( !empty($_GET['post_type']) ) {
    	    $typenow = $_GET['post_type'];
        }
        // try to pick it up from the quick edit AJAX post
        elseif (!empty($_POST['post_ID'])) {
            $post = get_post($_POST['post_ID']);
            $typenow = $post->post_type;
        }
        else {
    	    $typenow = 'nopostfound';
        }
    }
    
    $typenow_array = array( 'post_type_shows', 'post_type_characters' );
    if ( !in_array( $typenow , $typenow_array ) ) {
    	return;
    }
    
    add_filter( 'wpseo_stopwords', '__return_empty_array' );
    remove_action( 'get_sample_permalink', 'wpseo_remove_stopwords_sample_permalink', 10 );
    

    There was something funny to this, by the way. Originally I didn’t have the $pagenow code. Didn’t need it. But when I left it out, Yoast SEO broke with a weird error. It refused to load any of the sub-screens for the admin settings!

    Cannot Load Yoast SEO Admin Pages

    After some backpacking of “Okay, was it working before…?” I determined it was the call for global $typenow; – a global that isn’t used at all in the Yoast SEO source code that I could find. Still, by making my code bail early if it’s not even on a page it should be on, I made the rest of the WP Admin faster, and that’s a win for everyone.

  • Two Forks In The Road

    Two Forks In The Road

    I believe in healthy competition.

    Rivals, professionally and personally, have the ability to inspire us to reach great heights. They also have the ability to be terrible, but when a true rival, who respects you and your work, arrives, they should be embraced.

    The other day I said that I would love to see a W3TC killer. Killer was the wrong word, as what I mean is that I would love to see something as amazing as W3TC that reaches out and tackles caching in a new and inventive way. I’d also love to see a WordPress killer, an iPhone killer, and a Linux killer. And a Hybrid Car killer.

    I don’t mean I want any of those things to fail, I mean I want to see them have a challenger who does what they do, differently, in a way that inspires them to do more and more and better.

    Growth stagnates without good rivalry. When you have a rival who does what you do, and they succeed, you want to succeed. When you’re both healthy rivals, you can carry it even further. Reaching out to your rivals and telling them “I am impressed with how you did X! Nice job!” is the greatest gift. With WordPress code, taking a leaf from their book and forking some of their code (with credit) is another way to hat-tip them.

    In truth, W3TC and WP Super Cache never really competed. They can’t. They have wildly different approaches to just about everything, and they’re not even ‘after’ the same customer base. WP Super Cache appeals to people with it’s simplicity and directness. It works and you can (mostly) ignore it. W3TC has an insanely deep and complex set of tools that works closer to the base level of a server. W3TC has options, oh my god it has options, and they can overwhelm.

    But the real crux to all this, besides the take away that caching is hella hard, is that there is always more than one way to solve a problem. And there is always room for multiple solutions in any ecosystem. It comes down to needs, wants, and user preferences. Both plugins I’ve named here do a great job at meeting the needs for their audiences. And both plugins grew out of someone’s need. Donnacha and Fredrick both created something to solve their own problems. They shared these solutions with the world and became unintentional rivals and kings of caching.

    Okay so back to what I said.

    Should there be a ‘killer’ caching plugin? Will there be one?

    Maybe.

    There should never be one killer app, no matter what it is. There should never be one perfect solution. Mostly because I don’t believe there’s such a thing. There’s nothing we can create that will suit everyone’s needs and wants. It’s statistically impossible. So when we talk about a ‘killer’ anything we never mean that. We mean “There should be options and the options creators should be healthy competition with each other to create some awesome things.”

    And I really truly thing we should do that. I would love to see someone tackle WordPress with a serious self-hosted alternative. Something easier to install on my own than Ghost, but as easy as Hugo or Jekyll to write a post. Something extendable like Drupal, but with better backwards compatibility. Something next. And I want to see WordPress take what it learns from those other tools to become even more.

    Because healthy rivalry between friends and equals is a good thing.