Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: design

  • Keep A Name In Mind

    Keep A Name In Mind

    When you’re making your own project for small things, it’s not a huge deal when you try to think up a name. As soon as you realize your project is going to be shared with the world, however, the game changes.

    Project Names

    A project can be as massive as a new release of an operating system (Longhorn anyone?) or as small as a new plugin for WordPress. If could be a library for PHP or JS, or maybe a simple NPM add on. In all cases, the name you pick should be unique.

    This gets hard when you want to name a tool something like “Foo for Bar” like “Color Coding for Quickbooks.” Wy is that hard? Well while your name is certainly descriptive, it’s not unique. Because someone else can make the same tool. “Joe’s Color Coding for Quickbooks.” Or worse… “Color Coding 4 Quickbooks.” And the problem here is that neither of you really have the right to the name, do you? You’re both leveraging ‘Quickbooks’ and their brand, so where do you have a leg to stand on when someone uses a similar name?

    A unique name, though, like “Color Me Quickly,” would be so much better. Think of displaying it like this: “Color Me Quickly – A tool to colorize Quickbooks” and then having a description that talks about the idea and how to use it. “We love Quickbooks, just like you, but we hated the color schemes. We were always mixing up Receipts and Refunds. That’s why we came up with the Color Me Quickly tool. One simple install and we could see, right away, what was what. With our accessibility friendly default color schemes, and fully customizable colors, you can make your Quickbooks look how you need.”

    The name is unique, the description is SEO friendly, and you will be easily able to stand out in a crowd.

    Function Names

    Oh but then we have function names.

    If you’re a library, please please please remember to wrap your code in “If this code is already included, do not include it again” checks. PHP has function_exists() and class_exists().

    Using Javascript?

    if (typeof obj === "function") { 
        // Function is safe to use
    }
    

    The point here is that if you’ve made a library, always make sure it’s not already running before you try to run. This is a huge issue in WordPress land. With over 45,000 plugins, the odds that two will include the same libraries are pretty high. The odds that two will have conflicting versions? Right, you got it.

    But you should watch out with those checks. I’ve seen a lot of plugins use a check that if the function doesn’t exist, run their plugin. That’s a great idea, except that it’s not. If you name your function wp_get_post() and check for it’s existence before loading, what happens if it does exist? Your code won’t be called. And what happens if your code doesn’t get called? Your function won’t run. Your plugin won’t work as expected.

    Function and class names have to consider their world. A WordPress plugin should never use a non-prefixed’ anything. As Nacin says:

    It’s a simple concept. Anything you create in the global namespace has the potential to conflict with a theme, another plugin (including one you wrote), and WordPress core itself. Thus, prefix everything with a unique-enough character set.

    Be Unique

    Consider the environment that you code for when you name things. Always check for trademarks and possible conflicts before you name something you plan to release to the world. Remember to be unique.

    Also remember it’s 2016. All the good two and three character prefixes are probably taken.

  • Aiding Symbol Selection

    Aiding Symbol Selection

    Last week I was talking about the difficulties I was having with Symbol Selection. At it’s crux, the issue is explaining something visual that’s clear to me but may not be to others.

    What I ended up doing was making in-line documentation. When you edit a category, you see the option to change the icon, but now it has some exposition:

    Exposition has a link to help you visualize things

    This is pretty simple, I now, but the point is that if you get that far and go “Wait, what?” your eyes will hit that link and you’ll probably click on it and get the new Appearance page:

    A page to show you all the symbolicons

    The page is generated by an mu-plugin, and quite simply it scans the folder for all the symboicons and shows you each one. Since it’s in an mu-plugin and the images are a part of the theme, I put in an extra check to see if the folder is there and, if so, show an error.

    class SymboliconsSettings {
    
        public function __construct() {
            add_action( 'init', array( &$this, 'init' ) );
        }
    
        public function init() {
            add_action( 'admin_menu', array( $this, 'add_settings_page') );
        }
    
    	// Sets up the settings page
    	public function add_settings_page() {
    		$page = add_theme_page(__('Symbolicons'), __('Symbolicons'), 'edit_posts', 'symbolicons', array($this, 'settings_page'));
    	}
    
    	// Content of the settings page
    	function settings_page() {
    		?>
    		<div class="wrap">
    
    		<style>
    			span.cmb2-icon {
    			    width: 80px;
    			    display: inline-block;
    			    vertical-align: top;
    			    margin: 10px;
    			    word-wrap: break-word;
    			}
    			span.cmb2-icon svg {
    			    width: 75px;
    			    height: 75px;
    			}
    			span.cmb2-icon svg * {
    			    fill: #444!important;
    			}
    		</style>
    
    		<h2>Symbolicons</h2>
    
    		<?php
    
    		$imagepath = get_stylesheet_directory().'/images/symbolicons/';
    
    		if ( !file_exists( $imagepath ) && !is_dir( $imagepath ) ) {
    			echo '<p>Your theme does not appear to have the symbolicons folder included, so you can\'t use them. How sad. It should be installed in <code>'.get_stylesheet_directory().'/images/symbolicons/</code> for this to work.';
    
    		} else {
    
    		    echo '<p>The following are all the symbolicons we have to chose from and their file names. Let this help you be more better.</p>';
    
    			foreach( glob( $imagepath.'*' ) as $filename ){
    				$image = file_get_contents( $filename );
    				$name  = str_replace( $imagepath, '' , $filename );
    				$name  = str_replace( '.svg', '', $name );
    				echo '<span role="img" class="cmb2-icon">' . $image . $name .'</span>';
    			}
    		}
    	}
    
    }
    new SymboliconsSettings();
    

    It’s not perfect, but it helps.

  • De-fontification

    De-fontification

    I love fonts. They’re a great way to make your site unique. Back in the early 2010s, we were all using them all over the place.

    It’s time to retire them. (more…)

  • Too Many SVGs

    Too Many SVGs

    I was looking into moving a site from Font Icons to SVGs for a few reasons. The primary is that, with an SVG, images will look crisp on all monitors, including the non-retina displays. They literally look better on my crappy old MacBook, instead of just on my iPad.

    Once I had the one site done, I went to look at another. It was a smaller site, running a Hugo as a static site generator, and I thought it would be perfect.

    I was wrong.

    Using SVGs is Easy

    Replacing my font icon with an SVG was as easy as making my Facebook call this:

    <object type="image/svg+xml" data="/images/social/facebook.svg"><span class="screen-reader-text">Facebook</span></object>
    

    Done. It’s tiny (2kb) and there are six similarly sized images which makes for 18kb which is incredibly smaller than the 200kb or more that Font Awesome can be. Simply, I realized I was only using five of the icons (on every page) and how stupid was that? I don’t need the whole library!

    I will note that ‘styling’ SVGs can be an exercise in patience, since you cannot apply CSS styles when you embed as an object. Thankfully, I wanted to make the icon match my style so I edited the style directly (which is the topic of another post). If you use PHP, I recommend using file_get_contents() to get the contents of the svg, and then use normal CSS to style. I was using plain HTML. There are tradeoffs.

    Using too many SVGs sucks

    My initial tests, using the footer first, and my page loaded much faster. Elated, I jumped over to all uses of the fonts, and remembered I had a page that listed a series of items with star rankings (none through five). I changed the generator code behind that to be object icons and reloaded.

    The page was slow.

    It was like dialup modem slow. Absolutely painful.

    After some research, I ran into this post about why SVG was so slow, and found a graphic that explained it clearly.

    Render times per number of objects on a page

    What the graph demonstrates is simply that the more objects you have on a page, the slower it is. That part is obvious. The more anything on a page, the slower it is. So why are SVGs slower than PNGs? Why was I only seeing this on an HTML page with 50 images, and not on a WordPress generated PHP page with the same amount.

    The answer was because the SVGs have to be rendered on the HTML page. I was using <object> tags on the HTML and file_get_contents on the PHP. The way the PHP code works, it pulls the file into content and dumps it out, not processing. Since the files are so small, and since the there’s no object rendering involved, the rendered PHP was faster than a static HTML. In this case.

    Can It Be Faster?

    After I was done face-palming, I asked myself if it was possible to speed this up? Fixing this comes with understanding the cause. Once I determined that the issue was rendering the object and not the SVG itself, the solution unfurled before me.

    Instead of using object tags, I could include SVGs like this:

    <svg version="1.1" id="facebook" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
    x="0px" y="0px" width="50px" height="50px" viewBox="0 0 438.536 438.536" 
    style="enable-background:new 0 0 438.536 438.536;" xml:space="preserve">
    <g>
    <path class="social" d="M414.41,24.123C398.333,8.042,378.963,0,356.315,0H82.228C59.58,0,40.21,8.042,24.126,24.123 C8.045,40.207,0.003,59.576,0.003,82.225v274.084c0,22.647,8.042,42.018,24.123,58.102c16.084,16.084,35.454,24.126,58.102,24.126 
    h274.084c22.648,0,42.018-8.042,58.095-24.126c16.084-16.084,24.126-35.454,24.126-58.102V82.225 C438.532,59.576,430.49,40.204,414.41,24.123z 
    M373.155,225.548h-49.963V406.84h-74.802V225.548H210.99V163.02h37.401v-37.402 
    c0-26.838,6.283-47.107,18.843-60.813c12.559-13.706,33.304-20.555,62.242-20.555h49.963v62.526h-31.401 
    c-10.663,0-17.467,1.853-20.417,5.568c-2.949,3.711-4.428,10.23-4.428,19.558v31.119h56.534L373.155,225.548z"/>
    </g></svg>
    

    The downside is that this looks uglier. The upside? This is hella fast and it’s still lighter weight than including a font icon, and I don’t have to upload images.

    SVGs or Font Icons?

    This is a question for the ages. They can both be made accessibility friendly, they can both be optimized. Arguably, font icons are compatible with more browsers, but it’s also 2016 and if people are still on IE 8 (sorry banks), the Internet looks pretty shitty anyway. I can’t tell you which is better, and I find use for both in different situations. I love font icons a great deal, but just as I love WordPress, there’s a time and a place for them. And a time and a place for something else.

  • Making More With Less Work

    Making More With Less Work

    The other day, I added meta data of an icon to a custom taxonomy. When you need to add one or two filters to one or two items, it’s simple.

    add_filter( 'manage_edit-{my_taxonomy}_columns',  'my_terms_column_header' );
    add_action( 'manage_{my_taxonomy}_custom_column', 'my_terms_column_rows', 10, 3  );
    

    Replace {my_taxonomy} with your taxonomies, call it a day. But when you add in two, or three, or four, you don’t want to make four, or six, or eight lines of code. And when you’re calling the same array over and over, it’s time to get smart.

    Make An Array

    I originally only want to do this custom work in one taxonomy, so it was no sweat to repeat a little code. But then I realized I wanted to see it in four. Maybe more. So I picked out my array:

    $icon_taxonomies = array( 'tax_cliches', 'tax_chartags', 'tax_gender', 'tax_sexuality' );
    

    I made this outside the two functions, because I knew I was going to need it in multiple places. It would necessitate me tossing global $icon_taxonomies; into every function that needed it, but that was okay. Better that then trying to make sure every time I updated an array, I did it in all the places. Once is better.

    Make Your Loop

    The easiest thing was to trigger this on admit_init. Grabbing my global, I ran a simple for-loop from that array and added a filter based on the taxonomy named stored in the array:

    add_action( 'admin_init', 'my_add_taxonomy_icon_options' );
    function my_add_taxonomy_icon_options() {
        global $icon_taxonomies;
        foreach ( $icon_taxonomies as $tax_name ) {
    	add_filter( 'manage_edit-'.$tax_name. '_columns',  'my_terms_column_header' );
    	add_action( 'manage_'.$tax_name. '_custom_column', 'my_terms_column_rows', 10, 3 );
        }
    }
    

    Is It Really Less?

    A clever person will count the lines in this code (10 when you add in the variable) and think “Mika, you wrote two extra lines!”

    A more clever person will count the lines and think “At 5 taxonomies begins the break even point.”

    I know. From the outset it looks like I’m taking more time to over-engineer the solution to a very simple problem. And while I am, I’m also making it easier not to make typos and not to forget a step. I can make one change, one word, and update multiple places becuase that array is also used back in the my_register_taxonomy_metabox() function.

    'taxonomies'       => array( 'my_cliches', 'my_chartags' ),
    

    I removed the array and tossed in the new code.

    Yes, that’s adding two lines, but it removes my need to think “Where does this all go?” down to one place. And yes, I documented this in-line. The code header has a nice docblock explaining the whole section, what each variable is, and what each function does.

  • Project Bloat

    Project Bloat

    Can we have a serious talk about project bloat?

    During the framework kerfluffle, I remarked that I hated seeing a 10 line plugin needlessly include a framework like CMB2 because of the size of plugin it created. Someone remarked that if the library helped them write something in ten lines instead of 100, wasn’t that better?

    And the answer to this is maybe.

    My issue is not using a library when the library is the best solution. My issue is people defaulting to use a library before they think about if it is the best solution.

    And my point is really quite simple and obvious to a large number of developers. I’ve touched on it time and again. I’ve told you how I handle packaging my vendor folders. Simply put, I think that before you include anything in your project, you should evaluate it’s merits and flaws.

    Look. There are always, and will always be, good reasons to use a library. There’s never a reason to use a library thoughtlessly, and that’s what I see every day. By ‘thoughtlessly’ I meant someone who has a plugin that adds one setting, a custom meta field let’s say, into all posts. And in order to do that, they wrap ACF into their plugin.

    For one field.

    One.

    Literally one.

    Jackie Chan WTF Meme Face

    And I get it, I really do. The settings API is a bag of wet hair, and the fields API needs love (so much props to Scott Clark for his work there), and figuring out how to do things can be a comprehensive battle of trial and error vs ‘How much hair do I have left?’ And yes, I do use some of those libraries, like CMB2 and ACF, when the need calls for it. When I’m making a massive custom tool or theme and I need to do a million things. But …

    What I don’t do is use it for one field. Sure I could, but that would make my plugin very large and to no real benefit except it’s ‘easier’ for me. And even that is questionable. When I do use them, and yes I do, I do so thinking about the weight I add to my project.

    A pause here. I say this a lot, the weight of a project.

    Everyone seem to assume I only mean the size (in MB) of a project. I don’t. When I say the ‘weight’ of a project I mean the file sizes, of course. Making your 10kb plugin over 500kb just to add one field (I’m being literal here, folks) is sketchy at best. Making it over a meg is borderline ignorant. But I also mean the weight of how it impacts the speed of the site. Will having the library called make a site slower? It might. And I also mean the weight of technical debt. Am I going to update the plugin and the library every single time? This is my responsibility now, and I have to test and test and ensure I don’t break anything.

    The weight isn’t just the size, it’s the time sink. It’s everything that has to go into keeping a library included in a way that doesn’t conflict with anything else. It’s managing my time so I can test and evaluate changes. It’s making sure I push code that won’t break on new versions of my main project (i.e. WordPress). It’s making sure my changes don’t break other co-projects (like WordPress plugins and themes), by assuming they’ll always work on the newer versions. Backwards compatibility isn’t a requirement for all projects, but when it is, you bear that weight too.

    And the weight is also the fact that I’m robbing myself of a greater understanding of WordPress core. Using a library isn’t ‘cheating’ but it does mean I might be less capable of debugging a conflict, if it’s due to the library.

    That’s the real weight of a library included in your project. If you’re not considering it when you add a library, you’re doing yourself a massive disservice.