Half-Elf on Tech

Thoughts From a Professional Lesbian

Author: Ipstenu (Mika Epstein)

  • Review: Twitter vs Twitter

    Review: Twitter vs Twitter

    Like most people, I use Twitter. I don’t always use the official Twitter tools for that, though. For example, I rarely use the website itself as it’s slow and annoys me. I’ve almost always used Twitter apps on my computers, too.

    In July I decided to try using the official Twitter app again. I’d stopped when, at some point, they stopped working on it. Since they’ve picked it back up, I felt I should try it out. As a whole, I like it 90% but … well let me explain.

    Tweetbot

    This is my normal, go-to Twitter app. I’ve used it for a couple years, and it meets nearly all my needs for a Twitter app. I can have multiple accounts, which is a must-have for me, and it separates my @-replies from my likes/retweets. I really like that. It also makes those @-replies a different color in my timeline so they stand out.

    But… It only tracks likes/retweets for while the app is open. So if I log off, get a million retweets, and log back in, I’ll never know. Also it lacks some of the basic Twitter features like being able to report users and seeing if my other accounts have messages etc I need to pay attention to. I have to click to expand the other accounts to see what’s going on.

    Interestingly, all third party apps, be it iOS or MacOS, seem to have this issue with the notifications. They just can’t keep track if you’re not logged in. I’m guessing it’s a matter of the API and limiting calls. Most annoyingly, recently Twitterific has just stopped showing me @-mentions from people I don’t follow.

    Twitter

    Currently it has a brain and does everything you can do on the web. Multiple accounts, which I can see at a glance who has an alert or message, and it’s easy to switch between them. One click. I can see

    Downside? Sometimes when I log back in, the Live Stream is messed up. Also the notifications and mentions and replies are all jumbled up, in the worst ways. I can’t just see replies or likes or mentions. There’s no indication that a message IS a mention in my main-timeline. And the alerts that tell me I have an unread are for notifications and mentions combined.

    That I can’t easily find my mentions, which I want to reply to, sucks.

    So Which Wins?

    Right now, Twitter’s app is winning for the simple reason of easy user status, easy user switching, and actually being able to see all my likes/retweets. Which is important in some cases. It certainly sucks that I can’t easily identify my replies, and I can’t separate mentions from notifications like I can in the web-app, but the reliability of the API is (currently) worth it.

  • Demi Related Post Types

    Demi Related Post Types

    In my last post, I talked about relating posts to a custom post type. That is, how I listed the blog posts tagged with a show on the show page. Let’s do the reverse!

    Continuing the Click Hole

    While we’re very good about remembering to tag the posts we write with the shows they’re about, we’re not always as good with remembering to link the first instance of the show name to the show. That is, when we write about Supergirl we sometimes forget to link that to the page for her.

    That said, we still want to make it ‘easy’ for people to figure out where they can read more about the show. The ‘simplest’ way to do that would be to have a block at the bottom of each blog post. “Want to know more about the shows in this post?” or something along those lines.

    Relations Back Across Post Types

    The difficulty here is that if you want to get post data based on a post name, it’s easy. There’s a handy little function get_page_by_title() where you can put in this: get_page_by_title( 'Supergirl', OBJECT, 'post_type_shows' ); where Supergirl is the name of the show and post_type_shows is the post type.

    That’s well and good, but I knew there would be cases where the tag wasn’t going to match the name. People name shows pretty weird stuff (#hastag for example is the name of a show). Instead, I knew that I needed the tag slug and for that, I needed a different function: get_page_by_path()

    The Code

    Here’s the magic sauce:

    function related_shows( $content ) {
        if ( is_singular( 'post' ) ) {
    		$posttags = get_the_tags( get_the_ID() );
    		$shows = '';
    		if ( $posttags ) {
    			foreach ( $posttags as $tag ) {
    				if ( $post = get_page_by_path( $tag->name, OBJECT, 'post_type_shows' ) ) {
    					$shows .= '<li><a href="/show/' . $post->name . '">'. $tag->name . '</a></li>';
    				}
    			}
    		}
    		if ( $shows !== '' ) {
    			$content .= '<section class="related-shows"><div><h4 class="related-shows-title">Read more about shows mentioned in this post:</h4><ul>' . $shows . '</ul></div></section>';
    		}
    	}
    	return $content;
    }
    

    This has a few failsafes in there, like it only runs on single posts, it has to have at least one tag, and it has to have at least one tag that’s a show. Whew.

    After that, it’s just the CSS.

  • Semi Related Posts

    Semi Related Posts

    Once in a while you write some code that you’re pretty sure will never be useful to anyone else on the planet, but the idea is cool, so you want to share it.

    Hence this post.

    The Power Of Relations

    I was making coffee one Sunday morning, thinking about how I could keep turning a site into a wiki-level click hole, where a person could get lost for hours and days reading article after article. The reason WikiPedia works so well is that the content is all interlinked. Now, if you’ve never been a wiki editor, and you’ve just noticed that there are a billion links on every page, taking you around the universe, I’ll let you in on a secret. Those links are all human-made. A person goes in and makes those links, giving you ‘related’ posts.

    But WikiPedia really only works well due to the massive amounts of people who know weird shit and are willing to help and share. When it’s just you and your crazy friend running a site, that’s a lot of work. And you have wives and pets and kids to take care of. No, you want– you need to automate the heck out of this stuff.

    Related Posts are Hard

    Making related posts is a hard thing. There are myriad algorithms out there to calculate ‘relatedness’ and they’re all crazy complex. Worse, they all require a lot of processing power. There’s a reason Jetpack’s related posts feature runs on their servers. They’ve got more power than you do, and it stops people on shared from being nasty neighbors.

    This code is not a replacement for that code. This code is very specific and very targeted. It relies on people being clever (but not too clever). But when it works, it makes the interwoven data sets of a site work well. Because you see, we’re not talking about ‘If you like this article, read this other one…’ No. No we’re talking about crossing custom post types.

    Relations Across Post Types

    Hold on. I know what you’re thinking.

    The point of separate post types is not to cross the streams. Yes, I know. But that’s actually not true. Menus, for example, are a post type, and you a great many people want to have specific menus to their post types. That sounds logical, doesn’t it? Well, in this case, I have a post type for TV Shows, and I have regular old blog posts.

    My lightbulb moment was three-fold:

    1. When we write articles about the TV Shows, we logically use tags of the show name.
    2. Those show name tags match the slugs of the TV shows.
    3. If we link back to the articles from the TV Show page, then we’re getting people down the click hole.

    This meant my logic was simple: On the TV show page, check if there are any blog posts tagged with the show name and, if so, that post was ‘related’ to the show and therefore we should link back to it.

    The Code

    I put all this into a function so I could re-use it in a couple places. I like not repeating myself with code. I also have the function call another function, because I actually re-use this to connect different post types that all use the same tags. If you don’t need that, you can tighten it up.

    The Display

    This is in the theme:

    $slug = get_post_field( 'post_name', get_post() );
    $term = term_exists( $slug , 'post_tag' );
    if ( $term !== 0 && $term !== null ) { ?>
    	<section name="related-posts" id="related-posts" class="shows-extras">
    		<h2>Related Posts</h2>
    		<?php echo related_posts( $slug, 'post' ); ?>
    	</section> <?php
    }
    

    The Functions

    And here’s the function it calls:

    function related_posts( $slug ) {
    	$related_post_loop  = related_posts_by_tag( 'post', $slug );
    	$related_post_query = wp_list_pluck( $related_post_loop->posts, 'ID' );
    
    	if ( $related_post_loop->have_posts() ) {
    		$the_related_posts = '<ul>';
    		foreach( $related_post_query as $related_post ) {
    			$the_related_posts .= '<li><a href="' . get_the_permalink( $related_post ) . '">' . get_the_title( $related_post ) . '</a> &mdash; ' . get_the_date( get_option( 'date_format' ), $related_post ) . '</li>';
    		}
    
    		$the_related_posts .= '</ul>';
    	}
    
    	return $the_related_posts;
    }
    

    And here’s the function that calls:

    function related_posts_by_tag( $post_type, $slug ) {
    	$term = term_exists( $slug, 'post_tag' );
    	if ( $term == 0 || $term == null ) return;
    
    	$count = '5';
    	$query = new WP_Query( array(
    		'post_type'       => $post_type,
    		'posts_per_page'  => $count,
    		'no_found_rows'   => true,
    		'post_status'     => array( 'publish' ),
    		'tag'             => $slug,
    		'orderby'         => 'date',
    		'order'           => 'DESC',
        ) );
    
    	wp_reset_query();
    	return $query;
    }
    

    The Result?

    An unordered list of the last five related posts. You could add a link to ‘show more’ if you were so included.

  • The Monetization of Edge Sites

    The Monetization of Edge Sites

    When you’re starting out, the idea of making some passive income on your website is pretty appealing. So you look at services like Google Adsense or Project Wonderful, and you think that’s it. Sign up, toss some ads up, and you’ll make $.50 a month (yes, that’s fifty cents). For most people, that works quite well. But what happens when you’re not ‘most’ people?

    What Is an “Edge” Site?

    An edge site is a site that has a very niche audience. For example, 10 years ago, WordPress would have been a very niche subject and thus an ‘edge’ site if you were trying to get advertising. But if you said “It’s a technology blog” then you’d have a broader set of possible advertisers.

    Paradoxically, niche sites do better in Google search results, which makes them better traffic but harder to target. However, that’s not what an edge site really is. An edge site is a site that has content on the edge of what the various ad hosts would be comfortable allowing. And if they’re not comfortable, then they’ll close your account even if it’s just one of your domains that they don’t like.

    What Makes It Questionable Content?

    Have you ever read those terms of service? The ones you agree to when you sign up for ad companies? Of course not. But you kind of get the gist of what they’re on about. Basically they don’t want anything offensive on their networks, like promoting racism or bigotry. And there’s always a clause in there about “pornographic or sexually explicit material” — to whit, don’t have it.

    But what you may not realize is that sexually explicit also covers talking about sex. No, I don’t mean the erotica kind of content, I mean if I use Google Ads, I can’t have a website that gives you advice on sexual dysphoria, or even sexual health issues.

    How Do You Know if You’re Edge?

    You don’t.

    I found out because Google AdSense decided that a picture of two women in a bubble bath (which was a promo picture for a TV show) was too much. They cited it as being ‘adult’ and there was no further information as to if it was actually the image or if it was the post content. Yes, you read that correctly. They just said “This page is naughty!” and didn’t give me a chance to figure out what or why or how, except to experiment.

    Oh and if you experiment and get it wrong, you run the risk of losing the whole AdSense account, not just that one domain. Have a nice day.

    Google effectively doesn’t care about you. There’s no way to email someone and say “Hey, is the problem this one image or the subject matter of my site, which you approved 2 years ago?”

    What Are The Options?

    Now that I’ve scared you a bit, your choices boil down to:

    1. Find a lenient service
    2. Host ads yourself
    3. Rely on affiliate links

    They do really suck.

    Services

    The biggest issue with the services is that unless there’s a human-contact available, there’s very little you can do if you ‘break’ guidelines by being on that edge. I mentioned Google as the worst (if you have less than 500k page views a month, you’re outta luck), but Amazon’s not really much better unless you like auto-replies and stock answers. In my experience, the best people behind ads are Project Wonderful, but the quality of ads can be a bit low.

    Self-Host

    Even though I run my own, self-hosted, WordPress site, I loathe the idea of a self-hosted ad service. You can do it via WordPress plugins, but if you’re thinking they all look a bit janky, you’re right. They do. They’re all clunky in my eyes. Revive (formerly OpenX Source) is the nicest, but they’re not very fast and you have to maintain them. Which is an extra burden. And then it’s the damn hustle to get ads and manage them.

    Affiliates

    Lastly you have affiliates. Now they’re a curious mix of the most lenient, whereby I mean some like ShareASale will let you do anything but ‘adult’ and hate sites, and others like Amazon are super super picky. In both cases, though, they let affiliates approve you as an individual, so there’s that.

    Conclusion?

    If you want ‘easy’ money and you’re an edge or niche site that is possibly on that inane ‘family friendly’ bubble, you’re going to need to go with Project Wonderful. At least until you get big enough for BuySellAds to pick you up. Otherwise it’s a hustle to get the attention.

    Or you could try selling things…

  • Stopwords and Sort Queries

    Stopwords and Sort Queries

    The code I use is part and parcel from a comment Pascal Birchler made in 2015 and Birgir E. riffed on in 2016. I made one small change.

    The Problem

    People like to name TV shows with ‘The’ or ‘A’ or ‘An’ as the first word. “The Fall” and “The Good Wife” for example. However, when we order such things in a human sensible way, “A Touch of Cloth” should be listed behind both of those.

    • Frankenstein
    • The Fall
    • Grey’s Anatomy
    • The Good Wife
    • A Touch of Cloth

    WordPress, though, sees them as absolutes and you get this:

    • A Touch of Cloth
    • Frankenstein
    • Grey’s Anatomy
    • The Fall
    • The Good Wife

    Not quite right, is it?

    The Fix

    This code does two things.

    The first part is the filter on the posts_orderby function. That checks if the post type is the one I want to filter (in my case, only shows), and if so, use regex to filter out my stop words of ‘the ‘, ‘an ‘, and ‘a ‘. The extra space in each word is important. I want to reorder “The Fall” and not “Then They Fall” after all!

    The second part is the actual filter on the title, to mess with it only for the ordering of posts.

    add_filter( 'posts_orderby', function( $orderby, \WP_Query $q ) {
        if( 'post_type_shows' !== $q->get( 'post_type' ) )
            return $orderby;
    
        global $wpdb;
    
        // Adjust this to your needs:
        $matches = [ 'the ', 'an ', 'a ' ];
    
        return sprintf(
            " %s %s ",
            MYSITE_shows_posts_orderby_sql( $matches, " LOWER( {$wpdb->posts}.post_title) " ),
            'ASC' === strtoupper( $q->get( 'order' ) ) ? 'ASC' : 'DESC'
        );
    
    }, 10, 2 );
    
    function MYSITE_shows_posts_orderby_sql( &$matches, $sql )
    {
        if( empty( $matches ) || ! is_array( $matches ) )
            return $sql;
    
        $sql = sprintf( " TRIM( LEADING '%s' FROM ( %s ) ) ", $matches[0], $sql );
        array_shift( $matches );
        return MYSITE_shows_posts_orderby_sql( $matches, $sql );
    }
    

    If you’re using MariaDB, this can be even easier, but I have to test on my dev site, which uses MySQL.

  • How Mobile is AMP?

    How Mobile is AMP?

    There are pros and cons of using AMP, the biggest being Alex Kras’ discovery that Google is kinda stealing your mobile traffic with AMP. But since WPBeginner lays out the pros and cons really well, I’m going to skip over that and discuss something else.

    Responsive Themes

    The concept of a ‘mobile only’ theme is one I generally deride. After all, if you’re on a website in 2017, it should have been written with the concept of mobile first. Most people design a site for their computer/browser of choice, and then add in resizes for mobile. Contrasting this is the idea that you build out your website for mobile browsers first, and then go back in and add in the larger views. That is Mobile First.

    It’s an ideal, I agree, and while I love it (and Carrie Dils who made the beautiful Utility Pro Theme as a mobile first them), it can’t always be achieved. Some websites are written to be ‘apps’ and they’re intended to be used as a browser app.

    In general, I support the use of a responsive theme, be it mobile first or not. This kind of theme will react based on browser size, or operating system type. But a mobile ‘only’ theme? I dislike them a great deal. They create headaches with caching (ask anyone who’s had their cache catch the mobile page for everyone!) and they can be difficult to jump back from, if someone is perhaps on a tablet that can handle the ‘full’ site. They also double your work.

    AMP

    AMP is a project by Google. The concept is a super light, ultra-fast mobile page for your sites. AMP is fast, it’s simple, and it’s a stripped down version of your normal site. How it works is that When Google searches your site and adds it to their big giant database, they can can see “Aha, this site has AMP! I will use it for mobile!” And then, when someone surfs to your site via a Google search, Google would notice “This user is on mobile! I will show it AMP displays!”

    The downside you might have noticed is that the AMP pages only get called when you’re doing a Google search. That means if you go to a website on your phone, you get the mobile responsive site anyway. Which is what Paul (and I) think you should be doing. And right away, you might think “Hey, I should make all my mobile visitors go to AMP!” and you may come up with code like this:

    function amp_redirect() {
    	if ( wp_is_mobile() ) {
    		$url = trim(  $_SERVER['REQUEST_URI'], '/' );
    		if ( substr( $url, -3) != 'amp' ) {
    			$url = $_SERVER['REQUEST_URI'] . '/?amp';
    			wp_redirect( $url );
    			exit;
    		}
    	}
    }
    

    That looks great, doesn’t it? It’s smart enough to check if the URL ends in ‘amp’ and, if so, not redirect. Plus it uses ?amp which means if the page doesn’t have an AMP URL, it won’t fail an ugly 404 death.

    There is, however, a big problem with AMP. You end up having two sites. Paul Bakaus talks about the pitfalls of a separate mobile site, and how you should keep a responsive theme for your site, and not use AMP for Mobile. This is not a good thing in the long run.

    A RESTful Alternative

    So let’s think about this differently and not in the simple “Mobile vs Non-Mobile” way. Let’s ask ourselves the real questions. “What is this site doing?” and “How will people be using this site?” Because the crux of the matter is really how is the data from the site being consumed!

    Recently, with the advent of the REST API, WordPress has as new way for people to eat your data. Much like I’ve talked about before, using the REST API to power an Alexa app or a plugin, the REST API can be used to power mobile apps! Yes, people are running iOS apps with the REST API. This lets you display the content however you want, even audio only, and yet power it fully with WordPress.

    In a way, you’re still making two sites, the app and the theme, but… You’re not making a generic theme that fits all users. You’re making a real application that fits the specific use case.

    What’s The Answer?

    Let’s break this down.

    1) Your theme should be responsive for mobile. Period.
    2) AMP is great for Google searches.
    3) The REST API can, and should power your apps.

    That’s it. Three steps to amplifying your site.

    Oh, and please don’t use that code I showed you. It’s sad.