Half-Elf on Tech

Thoughts From a Professional Lesbian

Author: Ipstenu (Mika Epstein)

  • ShareDaddy Genericons

    ShareDaddy Genericons

    I have a sneaky feeling that after I publicize this, it may end up as an option in Jetpack. After all, they already include Genericons.

    jetpackI’m using Sharing (from Jetpack) on a couple sites, and it works fairly well (the metrics were surprising that one one site they excel and on others they’re never used). That said, I didn’t like the images loaded for ShareDaddy, and it was a real Golidlocks moment. The ‘icon’ buttons were buttons within buttons, and with or without the text, that didn’t make me smile. The official buttons were too large and not matchy enough since everyone has their own design.

    sharing-buttons1

    So what’s a girl to to but fall back on her favorite toy in all the world, Genericons!

    There are only three steps, and the third is to have a drink. You ready?

    Change Sharing Links to “Text Only”

    It’s easier to do this via text only, though I’m sure you can do it with the others. I switched to Text. One click. Done.

    Edit your CSS

    Now I want to hide the text, put a Genericon before the link, and set the colors to ‘true’ for each item (that is, use Twitter Blue for Twitter, Facebook Blue for Facebook, Google Orange for Google+ etc). I picked silvery-grey for email. Also I think it’s correct to use display:none to hide the text, since screenreaders will still read it, and that’s okay. Could be wrong. CSS is not my super-power.

    div.sharedaddy a.sd-button {
        padding: 2px!important;
    }
    
    div.sharedaddy .sd-content li a::before {
        font-family: 'Genericons';
    	font-size: 16px;
    	color: #fff;
    }
    
    div.sharedaddy a.sd-button>span {
        display: none;
    }
    
    div.sharedaddy .sd-content li.share-twitter a::before {
        content: '\f202';
        color: #4099FF;
    }
    div.sharedaddy .sd-content li.share-facebook a::before {
        content: '\f204';
        color: #3B5998;
    }
    div.sharedaddy .sd-content li.share-google-plus-1 a::before {
        content: '\f218';
        color: #DD4B39;
    }
    div.sharedaddy .sd-content li.share-tumblr a::before {
        content: '\f214';
        color: #2C4762;
    }
    div.sharedaddy .sd-content li.share-email a::before {
        content: '\f410';
        color: #666666;
    }
    

    This isn’t perfect, since there’s no Genericon for Printing, Digg, Reddit, StumbleUpon, or Pocket at this time. I’ll be suggesting it to Joen soon. Interestingly, Font Awesome (which could also be used for this) doesn’t have Reddit or the other social networks either, but it does have a print icon. Me? I don’t need them for this site, so it’s okay.

    myshare

    Looks great, scales well on high-def devices, and it pleases me. By the way Pinterest’s red is #C92228 from what I can tell.

    Have a drink

    Like I said, step three to was to have a drink. You’re done!

  • Genesis: Static Nav Bar

    Genesis: Static Nav Bar

    One of my sites got a facelift, and mid-stream I thought “This site would be the perfect place to have one of those floating nav bars.” You know, like how Twitter has this?

    sticky bar example

    Well guess what? It was easy! Presuming you already have a Primary Navigation Menu (like the one I have here with the Genericons), it’s two steps. Of note, you don’t have to do this in your functions.php, but since this will be a part of your theme, it probably belongs there. I tested, and it works in an mu-plugin as well. I should also point out that there are some official directions in the My.StudioPress.com site, but I didn’t use them. I like making it hard.

    Step One: Put the nav menu above your header

    This one was super easy, it’s even in one of the official Genesis Snippits under Navigation Menus. Put this in your functions.php file:

    //* Reposition the primary navigation menu
    remove_action( 'genesis_after_header', 'genesis_do_nav' );
    add_action( 'genesis_before_header', 'genesis_do_nav' );
    

    That puts the primary navigation menu above the header. If you want to use the secondary menu, it would be genesis_do_subnav but you can sort that out.

    Step Two: Make it stick

    This is pure CSS, so into your style.css goes:

    .nav-primary {
        position:fixed;
        z-index:99;
        top: 0;
        width: 100%
    }
    

    At first I didn’t add in the top: 0; but I found out that without it, a fixed position meant my header was suddenly under the navbar all the time. Oops. So I moved that to on, after spending an hour trying to math out the permutations with margins, and ended up with my navbar under the WordPress toolbar! Don’t worry, CSS to the rescue!

    body.admin-bar .nav-primary {
        top: 28px!important;
    }
    body.admin-bar .site-container {
        margin: 30px 0 0 0;
    }
    

    This simply says that for the body class of admin-bar, bump everything down by 28 pixels.

    Step Three: Return to Top

    I know, I know, I said two steps. This one is optional. I made a menu item called ‘Top’ with a link of #top and a CSS label of ‘top’ and it looks like this:

    Top Menu

    Now since I called this menu ‘primary’ and I’m using Genericons, I made this my CSS (keep in mind .nav-primary would also work):

    .menu-primary top {
        float: right;
    }
    
    .menu-primary li.top a {
        font-size: 0;
    }
    
    .menu-primary li.top a::before  {
        vertical-align: middle;
        padding: 0 5px 0 0;
        font-family: 'Genericons';
        content: '\f435';
    }
    

    This gives me a happy little top arrow that, when clicked on, takes people to the top. If you want to mess with colors, remember that to be specific for just the before calls, it’s a:hover:before (the pseudo-element is last).

  • Writing Evil Code

    Writing Evil Code

    Malicious CodeLately I’ve been doing a lot more training than ever before, and I think (Jen, tell me if I’m wrong) I’m decent at it. I certainly know I have issues with planning exactly what I’m going to teach, though in the case of WordPress troubleshooting, I’m not teaching people what the right answer is, but actually how to look at the error in order to find the right answer. It’s like a code philosophy class, and the more I give it, the more I think I should go back to school to actually ‘learn’ this stuff.

    One thing we’ve been learning about all this stuff, though, is that the hands-on lessons go way better than the lectures (to which every one of you is going ‘Duh, Mika!’ I’m sure), and in the interests of that, I’ve been writing intentionally bad and evil plugins. Actually, Kailey Lampert wrote most of the bad/broken plugins, and I’ve been writing the evil ones. I have a hard time writing broken, as it turns out.

    On the other hand, when it comes to writing intentionally nefarious code, it’s pretty easy. Either that or I’m actually really good at it and don’t think I’m not pondering what that means about me.

    The following are some of the one’s I’ve not only written, but explained what they do, why and how.

    Computers with Errors

    • I Love DC: When installed and activated, you will be redirected elsewhere. Forever.
    • I Love San Diego: Changes your password to something you have no idea what it is, and also changes your email so you can’t easily reset.
    • Hello D0LLY: Redirects non-logged in users to a different site.

    Now it’s intended that all these plugins are simple. They don’t take long to fix your site, and they don’t take long to decyrpt and understand. Every page where you can download them even tells you how to fix them. The point of them is not to make super complex hacks that can never be detected (no such thing), but to explain the process of how one looks through your own site to figure out what happened, and then the plugin file itself to see why it happened at all.

    You see, I’m not aiming for these to make someone the world’s best coder. The goal is to help people understand what’s going on and in general, how to un-do it. Personally, I’ve found that these are great ways for me to understand better how naughty people do things, but also the unraveling has proven delightful for people wanting to learn more about code and cleaning up sites. The only worry left with that is hackers might see this and get great ideas of what do to people. I finally decided that since I’m showing you all how to fix this, you’d know what was wrong when you saw it.

    If you want to download these hacks, check out Break/Fix over on my ElfTest network, and download away. Every example comes with a walkthrough on how to solve it, so if you need a hand held, it’s there for you.

  • Privacy and Evil and Money

    Privacy and Evil and Money

    Google likes to say ‘You can make money without doing evil.’ It’s right in their Company Philosophy.

    I’ve never bought into that. I mean, I agree you can do it without being evil, but I think that evil is highly subjective and what I feel is evil may not be what they do. Case in point would be endorsements.

    Maybe you’ve noticed when you Google search, sometimes your friends’ recommendations pop-up in the results. Like I searched for fabric stores and got results from my BFF, Andrea. That was amusing, but also disturbing. See, there’s a big difference between search results, and results in ads.

    Let’s step back. Here’s what Google says about their ‘endorsement‘ system:

    Google makes it easy for you to get great recommendations from your friends. For example, when you visit the Google Play music store, you may see that a friend has +1’d a new album by your favorite artist. When you search for a restaurant, you may see an ad including a 5-star review by another friend.

    That sounds pretty cool, right? My friends, people I follow on G+, contribute to my results. That’s sensible, since one presumes I share some interests with my friends. But then you scroll down the page and see a section about endorsements in ads.

    This setting below allows you to limit the use of your name and photo in shared endorsements in ads. It applies only to actions that Google displays within ads; the “Summertime Spas” example above shows a shared endorsement appearing in an ad on Google Search. Changing this setting does not impact how your name and photo might look in a shared endorsement that is not in an ad — for example, when you share a music recommendation that is displayed in the Play Store. You can limit the visibility of activity outside of ads by deleting the activity or changing its visibility settings.

    google_moneyLet me get this straight. People pay for ads on Google, so Google is making money. People click on the ads, so the advertiser makes money. My ‘endorsements’ are posted, without my permission, to drive traffic to those ads to make people money. I am not paid for this service.

    Thanks, Google. Guess what I just unchecked?

    Look, if you want to use me in search results, that’s one thing. Using me in ads is another. If a company took a comment I made in email and used it on their site to say “The Half-Elf loves our cocoa!” without asking me first, I’d be upset. I don’t ever expect to be compensated for my endorsements, but I do expect to opt-in to them. Here’s a real world example. I went to a spa and they had a ‘fill out this card to tell us what you think’ thing at the end. At the bottom was a box. “Check here if we can use your comments, or excerpts there of, in our advertising.” I thought about it, looked at what I wrote, and checked the box.

    But they let me opt in. They asked me for my permission to use me to make more money than the money I gave them for services rendered. I have no idea if they did use what I said, but I liked that they asked (and I liked the services) so I went back a couple times before moving across the country.

    I wish Google understood that sort of respect.

    Have a read of their updated TOS just for fun.

  • WP Comments ReplyTwo

    WP Comments ReplyTwo

    WPTavern has this cool thing where, without threaded comments, you still have a reply link, AND it creates an automatic link back to the original comment.

    Let me rewind. If you have threaded comments, then you get a ‘reply’ link on the bottom of a comment, and it lets you make a threaded reply. Yay! There are problems with this, though, as after a while, if you get nested deep enough, you can’t reply under anymore, and have to go up to click reply on the previous post and on and on.

    Threaded PipeBack eons ago, WPTavern solved this with a function, and like all great sites documented it! The problem? The documentation was busted. Now, yes, I did ping Jeff about this and asked him how it went, but in the meantime, I was impatient and looked up a plugin that almost fit my bill.

    Enter @ Reply (aka Reply To), which add in a reply link to all comments! Plus is gives you ‘Twitter like’ @replies, so when you comment, it starts “@foo:” automatically. This is just like what WPTavern has, perfect! Except… not quite.

    My problems became two:

    1. I want all comments to have a ‘reply’ link.
    2. I don’t want the hover over image.

    And I solved this with two code chunks: a plugin and a theme.

    See, by default WP stops showing you the ‘reply’ link when you can’t nest anymore. To change that, you have to edit how your theme calls comments. Or rather, you have to change the comment_reply_link() call.

    The Theme Code

    I’m already customizing my comments in Genesis so this was surprisingly simple.

    What was this:

    <div class="comment-reply">
        <?php comment_reply_link( array_merge( $args, array( 'depth' => $depth, 'max_depth' => $args['max_depth'] ) ) ); ?>
        </div>
    

    Becomes this:

    <div class="comment-reply">
        <?php comment_reply_link( array_merge( $args, array( 'depth' => 1, 'max_depth' => 2 ) ) ); ?>
    </div>
    

    Basically we’re lying to WP and saying we always show the link. I got that idea from this stackexchange post, and as I understand it, we’re tricking WP by saying that every post is depth of 1, and has a max of 2, instead of letting it figure it out on it’s own. This is probably inelegant, but I couldn’t find another way to have the reply link always on.

    The Plugin Code

    nested-commentsThis was easier, in that I took the existing code, cleaned it up and removed the reply image, and that was pretty much it. Downside is that this does not work on every site. Notably, it doesn’t work unless threaded comments are turned on. When they’re not, it does a double-refresh.

    That said, this is probably never going to be a plugin for the masses, so I’m content with having it work this way for me. Even if I only thread one comment at a time, it would let me group them together and get the @-reply. It’s already rather popular on the site I intended it for, and people like it.

    So here’s the code:

    class AtReplyTwoHELF {
        public function __construct() {
            add_action( 'init', array( &$this, 'init' ) );
        }
    
        public function init() {
    		if (!is_admin()) {
    			 add_action('comment_form', array( $this, 'r2_reply_js'));
    			 add_filter('comment_reply_link', array( $this,'r2_reply'));
    		}
    	}
    
    	public function r2_reply_js() {
    	?>
    		<script type="text/javascript">
    			//<![CDATA[
    			function r2_replyTwo(commentID, author) {
    				var inReplyTo = '@<a href="' + commentID + '">' + author + '<\/a>: ';
    				var myField;
    				if (document.getElementById('comment') && document.getElementById('comment').type == 'textarea') {
    					myField = document.getElementById('comment');
    				} else {
    					return false;
    				}
    				if (document.selection) {
    					myField.focus();
    					sel = document.selection.createRange();
    					sel.text = inReplyTo;
    					myField.focus();
    				}
    				else if (myField.selectionStart || myField.selectionStart == '0') {
    					var startPos = myField.selectionStart;
    					var endPos = myField.selectionEnd;
    					var cursorPos = endPos;
    					myField.value = myField.value.substring(0, startPos) + inReplyTo + myField.value.substring(endPos, myField.value.length);
    					cursorPos += inReplyTo.length;
    					myField.focus();
    					myField.selectionStart = cursorPos;
    					myField.selectionEnd = cursorPos;
    				}
    				else {
    					myField.value += inReplyTo;
    					myField.focus();
    				}
    			}
    			//]]>
    		</script>
    	<?php
    	}
    
    	public function r2_reply($reply_link) {
    		 $comment_ID = '#comment-' . get_comment_ID();
    		 $comment_author = esc_html(get_comment_author());
    		 $r2_reply_link = 'onclick=\'return r2_replyTwo("' . $comment_ID . '", "' . $comment_author . '"),';
    		 return str_replace("onclick='return", "$r2_reply_link", $reply_link);
    	}
    }
    
    new AtReplyTwoHELF();
    

    Most of the javascript stuff is copy/pasta for me (just left of witchcraft), and I left it barebones (no configurations) on purpose. Simple is as simple does.

    Suggestions and tweaks welcome!

  • Speaking at WordCamp Boston

    Speaking at WordCamp Boston

    I’ll see the East Coast, flying to WordCamp Boston on Oct 25-27th.

    A Tale of Two Servers

    Sunday I’ll be speaking about WordPress Managed Hosting on Sunday, and you’ll finally learn what all those Sherlock photos were about!

    There are still tickets available for the whole show, so grab yours now and come see me and a pretty damn awesome lineup of speakers.

    See you soon!