Half-Elf on Tech

Thoughts From a Professional Lesbian

Author: Ipstenu (Mika Epstein)

  • The Invisible Facets

    The Invisible Facets

    I’ve been using FacetWP for a year or so and it’s, hands down, the smartest WordPress plugin I’ve ever bought. Certainly I could have coded it, but not having to and being able to extend it to do what I need has saved me months of work and support.

    This is not to say it’s perfect. I’ve run into multiple quirks and headaches that resulted in me writing weird code to solve. And the solution to the null entry was no different. But it was, at the end, solvable.

    A Null Entry

    The majority of my data is saved in custom taxonomies. This makes it easy for me to grab and process. It’s also easy to list, because I can point people at /taxonomy/term and FacetWP magically populates properly in the sidebar.

    However. In one case, I have a checkbox. This is a simple post-meta to say if we love a show or not, and that check box, if it exists, is detected by FacetWP and I can easily get a list of all loved shows. The reverse is, sadly, not easy.

    That’s because if the checkbox is empty, there is nothing saved. No post meta. And if there’s no data, then when FacetWP builds out it’s list, there’s nothing saved for the non-existent data, and therefore no way to list nothing.

    An Imaginary Entry

    The other problem, related to this, is that I use Taxonomies in a different way. That is, while I use them like everyone else does with tags and categories, I also use them to track ‘stars’ – gold or silver etc. Obviously that makes it easy to track with /stars/gold/ buuuuuuut what if I wanted to list all the shows without any stars?

    How do I tell FacetWP ‘if there’s no taxonomy data saved for this, use a default?’

    A Fake Facet

    The answer lies within making a fake, that is unused, facet.

    The tl;dr to how FacetWP works is that it generates it’s own table with the data it collects from it’s facets. In general, there’s a 1-to-1 relationship with the facet and how it outputs. If you’re saving the terms of a taxonomy (like star colors), then there’s an entry in the database for the show and it’s star. If something has multiple values (like tags) then it has multiple entries.

    You can then alter the

    The Facet

    In order to make entries for my null or imaginary values, I made a facet that I didn’t use that I called all_the_missing and I gave it the data source of “Post Types”:

    An example of the facet

    The rest doesn’t matter. I’m not planing to display this, and I picked post types because it’s a quick bit to add the database without making it too heavy or complicated. Also I know it’ll exist for all my data.

    The Filter

    The magic to all this is my filter for facetwp_index_row:

    if ( 'all_the_missing' == $params['facet_name'] ) {
    	// If we do not love the show...
    	$loved = get_post_meta( $params['post_id'], 'shows_worthit_show_we_love', true);
    	if ( empty( $loved ) ) {
    		$params_loved = $params;
    		$params_loved['facet_name']           = 'show_loved';
    		$params_loved['facet_source']         = 'cf/shows_worthit_show_we_love';
    		$params_loved['facet_value']          = 'no';
    		$params_loved['facet_display_value']  = 'No';
    		$class->insert( $params_loved );
    	}
    	// If there are no stars
    	$stars = get_the_terms( $params['post_id'], 'the_stars' );
    	if ( empty( $stars ) ) {
    		$params_stars = $params;
    		$params_stars['facet_name']           = 'show_stars';
    		$params_stars['facet_source']         = 'tax/the_stars';
    		$params_stars['facet_value']          = 'none';
    		$params_stars['facet_display_value']  = 'None';
    		$class->insert( $params_stars );
    	}
    	return false; // skip default indexing
    }
    

    Now this is also wrapped in an if ( get_post_type( $params['post_id'] ) == 'post_type_shows' ) {...} check so this particular one only runs when shows are saved. But you can see what I do is when I run that specific facet, I check if the other data is available and if so, save it.

    Improvements

    I’d like to actually not have to save data when I don’t need it, but the need is enough that having this work was paramount. I can now sort when there’s no data, and that was what I needed.

  • Hey, Twitter, Why Do You Hate Us?

    Hey, Twitter, Why Do You Hate Us?

    Hi, Twitter.

    I know we fight a lot. You know I report a lot of abuse and harassment, and you do nothing about the Nazis, and we have our differences. But this isn’t about that. I mean, yeah, I’m salty about the Russian thing, but we need to talk about something else.

    We need to talk about using Twitter on a desktop when you have multiple accounts.

    Multiple Twitter Accounts Happen

    I have a legit reason to have multiple accounts. A good one, in fact. I have my personal account, but I have two others for brands I manage. And that means I kind of need to be able to log in to all three at once and wrangle things.

    If you use Twitter on the web, your choices are regular Twitter or Tweetdeck. The latter makes you sign up via a very convoluted process in order to grant access to accounts. Basically, you have to give your ‘main’ account access to the ones you want to manage. It’s not very obvious.

    And there are weird things missing from Tweetdeck. Like … no decent notifications. You can’t tell what you’ve read or when people @ you or anything like that. Not easily. Oh, and there’s no GIF button.

    Finally … with three accounts I get to have NINE columns. Three each for ‘home,’ ‘mentions,’ and ‘messages.’ Thanks. A lot.

    No Great Desktop App

    Here’s my problem. There’s no good Twitter desktop app. Your own app went unloved until you pulled the plug. In a tweet. Nice. Really nice. That leaves me with a few choices.

    TweetBot: I like Tweetbot, except that I can’t see polls in it, and I can’t navigate to embed Gifs. But it has a pretty decent interface. The biggest issue is that you can’t see group DMs. Sometimes keep on top breaks. Sometimes not.

    Twitterific: This is a wonderful app except that scrolling sucks. If you switch to a different account, keep on top stops working, and ⌘↑ (which should take you to the top of whatever you’re on) doesn’t scroll right. Oh and no embedding Gifs. And again, no group DMs and no polls.

    What about TweetDeck’s desktop app? It hasn’t been updated since 2015. The best version I’ve seen is Tweeten but again, I’m back to 3 columns per account.

    What I Want Is Simple

    I want the iOS app, but for the desktop. I want to have the following features:

    1. Multiple Account Support
    2. One visual ‘column’ per account (it can have sub tabs, whatever)
    3. The ability to insert and read polls
    4. Support for multi-person DMs
    5. Notifications
    6. A damn GIF button

    Instead, I get to use Tweetdeck in my browser. At least, until Twitter dumps that too.

  • Let’s Talk, Slack

    Let’s Talk, Slack

    Hi, Slack. You’re the cool product everyone uses to communicate on scale. You’ve introduced a lot of features and aspects that are great. We all like to use you for our non-company work, but I’ve noticed something interesting.

    See. You constantly remind us that Slack is for Business. But you don’t seem to have actually spent enough time in corporate land to understand what that means. So, as someone who worked for nearly 15 years (and recently at that) with The Man, and the last five with a smaller company, let me try to explain to you what mistakes you’re making. Oh, and before anyone asks, yes, I’ve pitched all of this in tickets/suggestions to Slack already.

    Constant Barrage

    Being able to tune alerts on Slack is basically the only way you have to live or die. I can mute channels or group-chats pretty easily, to allow a conversation I need to be aware of, but not right now to carry on around me.

    What I can’t do is mute my really, really, really chatty and annoying coworker for an hour so I can get work done.

    Oh sure, Slack, it’s passive aggressive to just mute Bob over there who knows I love the Cleveland Problematically Named Baseball Team, and wants to tell me something I will care about in an hour or so. But right now? I have a job. And I want to concentrate without your alerts popping up on my screen and showing that dreaded unread icon. And yes, Slack, I could mute everything, but what about my coworker Jane, the nice one who pings me with an apology because she knows I’m super busy, but she has a critical work problem, and I’m the expert.

    Come on, Slack.

    Asynchronicity vs Work/Life

    While everyone in startup land likes to brag about how they work 80 hours a week, the reality is that most business aren’t actually that stupid. We take vacations. We don’t work weekends. We like to spend time with family, go to a sports game, and not  be distracted by the ping of work.

    While you have do not disturb settings, Slack, I can only set them for specific hours. So yes, I do set them for 4pm to 7am, because I actually do have an end of day. But I can’t set my work days, I can’t connect Slack to (say) my Google Calendar and have it automatically detect that I’m out of the office. I have to constantly fiddle and tweak things. It’s a mess.

    Out of Office Messages

    Speaking of this, if I (perchance) happen to forget to mark myself as out of the office, I’m going to get alerts. Fine, that’s on me. But. You introduced custom status messages, which you tout I can use to announce I’m on vacation. Awesome! Now can you make them useful?

    See the problem is I put in “Out of the office until Feb 20” pretty recently, and I thought “My coworkers are intelligent, they’ll see this message and know ‘Aha! Mika is out!’ They don’t. And looking at this, I can’t blame them becuase of two things:

    1. Readability on MacOS is shit
    2. The message doesn’t fully show on iOS

    Don’t believe me? Here:

    Slack Example from iOS
    Slack example from MacOS

    Those are hard to read! And why don’t they auto-alert like a DND message does when someone DMs me? “Mika is currently [status message]” — Oh yes, Slack, I know people like to use those for jokes. Want to stop them? Make them auto-reply. Then people would only use them for real.

    And by the way…

    You’re Ageist

    Let me tell you a story.

    Once upon a time, not very long ago either, I supported desktop software. I received a phone call from someone in the Big Building, aka where the real bankers worked, and she couldn’t use a product because the screen was unreadable. She couldn’t see the buttons or dropdown. I asked her to give me 30 minutes and I would call her back. Quickly I went through a few steps to size and resize the window, and I couldn’t figure it out. I called her back and asked if I could come to her office.

    One 20 minute bus ride later, I’m at the fancy building, going through metal detectors, and I head up to her floor. I apologize for not being in a suit and ask her to please show me her desktop. One glance and I realized the problem was that her desktop itself had been resized. I explained I was going to change the resolution, resize it, and see if that fixed it. I promised I would reset everything.

    Nervous, she allowed this. After all, if I closed a specific window, I could cost the company a hefty bit of money. I very cautiously (without minimizing anything), changed the resolution.

    “Oh, that’s how it was this morning! My coworker was using my workstation.”

    After I head-desked a few times, I checked the app I was responsible for. It was set to take up most of the screen but not all. I resized it, manually, and then restored her preferred resolution. I then wrote down how I did that, how to fix it in the future, and went to give her coworker a stern word that began with “The first rule of using someone else’s workstation is THOU SHALT NOT MESS WITH THEIR SETTINGS.”

    A few years later, when I no longer worked on that team, I got a phone call from her again. “My new coworker is having the weird screen problem I had a million years ago. Can we pay you with lunch to fix it again?”

    Of course I said yes.

    Now re-read those problems I have with you, Slack. Because you’re worse.

    To Review

    I look at Slack, and I look at the problems I have, and I think “If I wasn’t technically competent, I would be lost.” And I realized “I am technically competent and I still get lost.”

    Slack. If you want to make it bigger, if you want big companies and banks to start using you instead of Lotus Notes Messenger, you need to step up your game. Provide business tools, the ones they need to make sure if they’re not available, someone knows who to contact next. Treat people like grown ups with mortgages, not 20-somethings who exist on packing peanuts and internships.

    Basically, Slack, you want the grown ups? Grow up.

  • What Is The Measure of a Site?

    What Is The Measure of a Site?

    After you think about where you’re saving your data, internally or externally, you’re going to be faced with the biggest problem known to exist.

    What do you do with your data?

    Common Data is (Mostly) Obvious

    Some data, as I’ve said before, is obvious. That is, you know what you want to do with statistics of visits. The base outset is ‘figure out how many people visit my site.’ Right? Not too hard. But that isn’t all you want to know. You want to know when your site is busiest, what content people read, and maybe you want to know on what device.

    You want to know these things because they can help you optimize what you do next. If, for example, your Monday posts are super popular, then you want to make sure you post them at the time the most people are going to visit your site. If you know only 2 people view your site on an iPad, maybe fixing that little annoyance can wait a bit.

    Rare Data is A Headache

    On the other hand, when you look at statistics for your complex data, like a site with TV shows and characters and actors, you have a completely different problem. What public stats are both relevant and meaningful? And how do you represent them in ways that people can understand?

    Like, do you use piecharts?

    An example of two pie charts

    They can be helpful but only if you don’t have a large number of data slices.

    I made a pie chart with 28 slices and it was unreadable. Though that was mostly because everyone had between 1-5% except for one that had 75%.

    The Question Is Usage

    This is a problematic question because it has no easily defined answer before you start building out your site. We’ve all seen an image of a paved path and then a foot-trail cutting away from it, or winding around an obstacle. People like to joke about how it’s design vs usage. While our goal when making any product is to avoid people walking off the paths, it’s unavoidable. And in the case of public statistics, it’s even harder to predict usage.

    A large reason for the problem is what is called a failure of imagination. This is, in part, the fault of the designers. That is, they didn’t predict things properly. Which requires metrics. Which can’t be gathered until people have used the site a little.

    You see the problem, I hope.

    Start With The Easy

    When I built out stats on my site, the ones I wanted people to use, I made sure to start with some easy things. Like those pie charts. Those are just pulled from a custom taxonomy which every character has. They’re simple. They’re easy. And they let people visualize.

    After I released it, someone asked “Could we have a chart to show how many actors a character has?”

    Actors per Character

    That was actually not easy, but the point is that by starting with something ‘easy’ I was able to inspire people to ask what they wanted to see.

    Don’t Be Afraid to Be Wrong

    Remember I mentioned that evil pie chart? You’re going to be wrong. You’re going to assume that the best way to show a specific data point is a pie chart when it really should be a bar chart. If you pick the right chart systems, it shouldn’t be too horrible to switch between them. But sometimes it will be.

    Just remember, it’s okay to make mistakes. You can dig up a path and repave it after all.

  • Processing Numbers with WordPress

    Processing Numbers with WordPress

    The very idea of ‘I should make statistics’ or ‘what are the metrics of this’ starts from the same place. We have a desire to understand what a thing is. Statistics, like traffic, and metrics, like speed, can tell us obviously important information about our sites. Faster sites do better. More traffic gets you more… whatever.

    But those are the obvious things. There are easy to understand numbers and there are difficult to process numbers. And it all matters where you save the data.

    Getting At The Data

    When I set about making statistics for LezWatchTV, the biggest problem I faced was determining what I wanted to show. Some things were simple. How many characters died and what percent of all characters was that? How many shows have dead characters?

    Since I chose to use WordPress features, like custom taxonomies, for the majority of the aspects of the site, getting those numbers was simple. There were, of course, some that were very difficult to get at, and this is fully of my own design. Sometimes there will be data you want to use that is just harder to get at than others.

    This means the question of understanding your numbers begins with understanding where they belong.

    Save Data in Smart Places

    I say this over and over. Use WordPress’ native features first.

    I mean use the taxonomies and the custom post types and the post meta wisely. But. When you’ve got a lot of data that needs to be cross related, consider saving it someplace else. For example, the reason FacetWP is so damn fast is that it doesn’t query WordPress all the time, and instead uses it’s own tables.

    Having it’s own table means there’s less overhead as they can make direct SQL calls to pull the data. When you have data spread across three post types, this becomes pretty much an imperative. You just have to script the code to save it properly.

    External Data

    While FacetWP does save data to it’s own tables, there is another option, and that is external locations. You’re most familiar with this with regards to Google Analytics. Some data makes sense to keep local, but keep in mind what you’re doing and what you’re generating with the data. When it’s just posts, local is perfectly logical. When you get into statistics… Well. Maybe you should export it.

    That brings up the next question. What data to you export, and to where.

  • Customizing Which Random Post

    Customizing Which Random Post

    Back in December, I posted about how I generated a random post of the day.

    After running it for 60 days, I realized I needed to exclude three things:

    1. Posts with a specific ‘placeholder’ image
    2. Posts with content ‘TBD’
    3. Posts with one of two specific meta values

    So today we will talk about how awesome WP_Query is.

    The Basic Query

    As a reminder, your basic query for a random post is this:

    $args = array( 
    	'post_type'      => 'posts',
    	'orderby'        => 'rand', 
    	'posts_per_page' => '1'
    );
    $post = new WP_Query( $args );
    

    Now, let’s extend it!

    Posts With An Image

    In this example, I have a very specific default image I use – the mystery person – to indicate the post doesn’t have it’s own image yet. I went and found the image in my media library and took note of the value – 949. Then I added a meta query which said “If the _thumbnail_id does not equal 949.”

    	'meta_query' => array( 
    		array(
    			'key'     => '_thumbnail_id',
    			'value'   => '949', // Mystery Person
    			'compare' => '!=',
    		),
    

    Seriously. It’s magic.

    Posts Without ‘TBD’

    We also have a standard convention for when we have a pending data post, but we need it for statistical reasons. Since, as of WP 4.4, you can use negatives in searches, just add this to the basic query:

    	's'              => '-TBD',
    

    This could be useful for your stores, if you wanted to list a product of the day but perhaps not ones with “Coming Soon” in the description. Of course, you should also have some meta flag but you get the idea.

    Posts With One of Two Values

    Okay. Here’s fun. Let’s say you have a post meta field called example_site_group and there are six choices in it but you only want one and two. Well, for that you need to use an array and a LIKE:

    	'meta_query' => array( 
    		array(
    			'key'     => 'example_site_group',
    			'value'   => array ( 'baseone', 'basetwo' ),
    			'compare' => 'LIKE',
    		),
    

    This is a little messier, but it certainly does work. Even with serialized data.

    Put It All Together

    Here’s the real code:

    // Grab a random post
    $args = array( 
    	'post_type'      => 'post_type_characters',
    	'orderby'        => 'rand', 
    	'posts_per_page' => '1',
    	's'              => '-TBD',
    	'meta_query' => array( 
    		array(
    			'key'     => '_thumbnail_id',
    			'value'   => '949', // Mystery woman
    			'compare' => '!=',
    		),
    		array(
    			'key'     => 'lezchars_show_group',
    			'value'   => array ( 'regular', 'recurring' ),
    			'compare' => 'LIKE',
    		),
    	)
    );
    $post = new WP_Query( $args );
    

    And voila.