Half-Elf on Tech

Thoughts From a Professional Lesbian

Category: How To

  • Yes, You Can Use Enqueues

    Yes, You Can Use Enqueues

    One of the battles I face with plugins is explaining to people that they really do need to use wp_enqueue_scripts() for their code. And often I get an argument back that they can’t because they need to include parameters.

    Hold on to your hats. You totally can.

    The Misconception

    It’s easy to get confused with code. There are so many different ways to solve the same problem, we get twisted around. Let’s say that you wanted to include the following script in your website:

    <script src="https://mycoolsite.com/widget.js" async></script>
    

    That’s pretty straightforward in WordPress:

    wp_enqueue_script( 'my-widget', 'https://mycoolsite.com/widget.js', array( 'jquery' ), 1.0.0 );<
    

    But. What if you wanted to add this as well:

    <script type="text/javascript">
        var _widget_options = {
            theme: 'slow' // Choose from 'fast', 'stop', and 'slow'. Remove this property to get the default theme.
    };
    </script>
    

    Now you clearly have to hand-code this into WordPress. Right?

    Wrong!

    Use Inline Scripts!

    You may have heard about wp_add_inline_script before. If not, don’t feel bad. What this does is add extra, inline, code to an already enqueued script.

    Which means that to add the extra code, you do this:

    wp_add_inline_script( 'my-widget', 'var _widget_options = { theme: "slow" }', 'before' );
    

    Which will echo out exactly what you need.

    The cool thing about this, is what if you want your plugin to have a lot of options? Like you want to use the value for an option to determine what your script should do?

    $my-widget-inline = 'var _widget_options = { theme: "' . get_option( 'my-widget-theme' ) . '" }';
    wp_add_inline_script( 'my-widget', $my-widget-inline, 'before' );
    

    And now you’ve got flexibility.

    Keep In Mind…

    First, the name of the script matters. If you enqueue it as ‘my-widget’ then you call it as ‘my-widget’ as the first parameter in your inline script.

    Second, you can change ‘before’ to ‘after’ if you need it to be after the script.

    Third, as with all things, make sure you only load your javascript when you must. No one likes a slow site because you’re loading your javascript on every page when it only needs to be on a specific custom post type.

  • Git Attributes: Control Your Vendor Folders

    Git Attributes: Control Your Vendor Folders

    When you’re developing code, a lot of the time you have vendor or bower_component folders that you don’t need. That is, you don’t need them for the code, but you do for the development.

    A year ago I explained how I handle my vendor folders. Essentially, I use SVN to ignore things so they don’t get uploaded to WordPress. And that’s great but

    What about Git?

    Enter Git Attributes

    The .gitattributes file lets you define attributes for paths. What that means is you can assign an attribute to a file which will then impact how various Git operations occur.

    Operations are things like checking your code out or pushing a release (something familiar to Githubbers). Basically an operation is when Git does a ‘thing.’ Whatever that thing will be. And the Attributes file allows you to specify what happens to specific files (or folders) when that thing happens.

    How Do You Use It?

    There’s a lot more to it than this, but if your goal is to exclude vendor folders and .git files from your zips to send them off to people, then you’ll want to have your .gitattributes file look like this:

    /vendor/ export-ignore
    .gitattributes export-ignore  
    .gitignore export-ignore
    

    This results in when you use GitHub and tell someone to download the zip from it, it will exclude those files.

    What Else Can I Do With It?

    Have a problem with line endings because one person on your dev team uses Windows? gitattributes can help.

    Need to make a change like that for everyone on a system? Or maybe you want to make sure you never include those vendor and documentation folders? The Pro Git Book says this:

    Attributes for all users on a system should be placed in the $(prefix)/etc/gitattributes file.

    Before you ask, unless you changed it, $(prefix) is nothing for pretty much everyone. You may have a /usr/local/git/etc/ location though.

  • FacetWP, JSON API, and WP_Query Searches

    FacetWP, JSON API, and WP_Query Searches

    One of the ways that FacetWP works is that it adds <!--fwp-loop--> to the source of your outputted page when it detects you used a search query and it can’t find it’s usual classes. This is so that it’s various features like refreshes and so on. It’s a good thing.

    At least it is until you’re trying to use a WP_Query based search to find titles “like” something, and you find your JSON output prefixed…

    Mostly Harmless

    Most of the time when you see <!--fwp-loop--> in the source code, you don’t care. It doesn’t impact anything and it helps Facet work. This is especially important when you have a ‘weird’ theme or plugins that mess with output.

    The issue is that this is how Facet decides if you need that output:

    $is_main_query = ( $query->is_archive || $query->is_search || ( $query->is_main_query() && ! $query->is_singular ) );
    

    Most of the time, that makes perfect sense. It just happens that I’m calling search in a place where that output is a bad idea. Like this:

    {“id”:6294,”name”:”Alex”,”shows”:”Witches of East End”,”url”:”https:\/\/tv.lezpress.dev\/character\/alex\/”,”died”:”alive”}

    Whoops.

    Annoying, But Not Impossible, To Fix

    After bashing my head in for a while, I grep’d the code for Facet, found where it was being set, and then read the help document on facetwp_is_main_query which told me that I could filter the function.

    In this case, I needed to set the value to false to get it to stop outputting, so I used this:

    add_filter( 'facetwp_is_main_query', function( $is_main_query, $query ) { return false; }, 10, 2 );
    

    Be careful where you put that by the way. If you put it on all pages, you’ll break your Facets. I put it in the function that generates the JSON output which limits it heavily, just as I want it to.

  • Fight For The Future: Battle for the Net

    Fight For The Future: Battle for the Net

    On July 12, 2017, we fight for the internet. Again.

    I know. Didn’t we just do this? Well we did, and we have to do it again.

    What Is Net Neutrality?

    Net neutrality is the principle that Internet providers don’t get to control what we see and do online. Think of it like if your phone company got to decide what numbers you could call and when. Back in 2015, we managed to get fairly strong net neutrality laws from the FCC (the US Federal Communication Commission) which stopped Internet providers from blocking, throttling, and paid prioritization—”fast lanes” for sites that pay, and slow lanes for everyone else.

    Isn’t that like TV?

    Yes it is! On your TV, you can only watch the stations you pay for. Now imagine the Internet that way. The problem though is that we don’t just use the Internet to watch movies. We use it to work, to develop code like WordPress, and to communicate world wide with like minded people to do all of that.

    What’s the battle for?

    Comcast and Verizon want to end net neutrality so they can control what we see and do online. It’s that simple. They want it to look like TV so they can say that we can’t work with our fellow developers in Serbia or Iran. They want to monitor all our communication with those people as well (which in the case of WordPress isn’t really a hinderance but still…).

    What can we do?

    Fight back!

    Change your websites so people see the damage being done. Inconvenience the hell out of them. Make everyone notice and get them aware. Even if they watch Fox News.

    The Fight for the Future has started the Battle for Net Neutrality just like they did in 2014 with The Great Internet Slowdown and like they do today with Blackout Congress.

    How do we fight back?

    Add the Battle For The Net Widget to your website.

    If you’re running WordPress, I made a Fight for the Future Alerts Plugin, which lets you decide which alerts you want to show. It currently only supports the upcoming Battle for the Net and the Blackout Congress, but I plan to add other on-going events as they occur.

    You can also use the Cat Signal which dynamically loads the right alert for you at the right time. The reason this is different is that not everyone wants to run an extra javascript all the time on their websites. Page speed is important after all. Plus they may not want to show every single alert.

  • Plural URLs

    Plural URLs

    URLs can be hard. When you have custom post types in WordPress it can be harder.

    Take, for example, a custom post type for videos. Do you want your URLs to be http://example.com/videos/video-name/ or http://example.com/video/video-name/ ? And do you want the archive to be http://example.com/videos/ or http://example.com/video/ ? And what happens when you change your mind?

    Thankfully, WordPress lets you do some weird things.

    Pick Your Default

    Let’s look at the video/videos idea for a moment. Individual posts should be video but the archive should be videos in order to grammatically make sense. When you make your custom post type there’s a parameter called has_archive – by default it’s false. If you make it true, then it’ll have the same ‘base’ as your custom post types.

    But. If you make it a string then you can make it ‘videos’ or ‘photos’ and magically your archives will have those names. That makes it pretty easy to change, just remember to re-save your permalinks after. I personally recommend doing a redirect so that video goes to videos (and videos/postname go to video/postname) so that any random bad URLs would still be caught.

    Remember that you can leave it false and make a page to be a placeholder page, or you use archive-{post_type}.php to customize it further.

    When You Need Both

    But… What if you need both?

    This is probably a bad idea, but let’s pretend you want to have both video and videos work for all cases. That’s when you’ll need something like this:

    $plural_types = array( 
    	'videos' => 'post_type_videos', 
    	'photos' => 'post_type_photos' 
    );
    
    foreach( $plural_types as $slug => $type ) {
    	add_rewrite_rule(
    		'^'.$slug.'/?$',
    		'index.php?post_type='.$type,
    		'top'
    	);
    	add_rewrite_rule(
    		'^'.$slug.'/page/([0-9]+)?/?$',
    		'index.php?post_type='.$type.'&paged=$matches[1]',
    		'top'
    	);
    }
    

    In that example, I have the slug for my custom post types set to the singular, and then the $plural_types array has the correct plural and the associated custom post type. This is tossed into a for-loop that creates a custom rewrite rule that will redirect.

  • Chassis – When VVV is Too Much

    Chassis – When VVV is Too Much

    When I need to do WordPress core development, I use VVV. It’s great for multiple versions of WordPress, a copy of WordPress Meta, and it’s all done in one go.

    But when I’m developing my own code, I want something a little lighter and simpler. I’ve been using Local for that for a while now. It involved a few weird tweaks but I was quite fond of it until the 2.0 upgrade. That’s because they broke the tool I needed most: Addon Volumes.

    The current status is that it’s broken and the developer misjudged how many people used it. These things happen, but for me this was the primary reason I used it. So that meant it was time to look at my options again!

    Chassis

    Made by the quirky and original Human Made, Chassis is a cross between VVV and Local.

    Like VVV, it’s Open Source. Like Local, it’s fast. Like VVV, it’s command line. Like Local, you can map to your hard drive. And that last reason was why I wanted to use it.

    Look. There are a lot of reasons to use Chassis. The fact that it’s a server, so you can test out things like Memcached and PHP versions and upgrades is a big one. The fact that it’s fast to install and setup is another. But at the end of the day, I need my dev environment to do the following things.

    1. Be ‘easy’ to rebuild
    2. Have access to WP-CLI
    3. Boot fast
    4. Have a GUI SQL editor
    5. Use my dev code, where I want it used from

    My Development, My Way

    The thing I hate about most dev environments is that they want you to put your code in their locations. MAMP, VVV, Local, and DesktopServer all prefer you to put your dev code in the folder for your dev site.

    I don’t work that way. All my code for all my WP sites live in ~/Development/repositories/NAME or ~/Development/github/NAME or ~/Development/wordpress/plugins/NAME and this is a system that works for me. I have all my dev code in the Development folder, and I’m consistent about it.

    Furthermore, when I use a local host install to test, I may use the same plugin on multiple sites. I try to reuse as much code as possible, after all.

    This means my headache is always trying to some how symlink my development folders to my development site. With MAMP and Desktop Server I used rsync (and I was sad). With Local I used the broken add-on. With Chassis, it’s actually built in!

    Build The House

    Chassis touts that it wants to be invisible. In order to do that, they separate WordPress and your code, recommending you put your code in the /content/ folder. This is great, but as we mentioned, I want to have my code in another spot, so I need to map folders.

    This can be done in the “Synced Folders” of the config.yaml file. I’ve added this:

    # Synced Folders
    #
    # You can sync as many folders as you like. We sync the nginx and php log folders by default.
    synced_folders:
        logs/nginx: /var/log/nginx
        logs/php: /var/log/php
        /Users/ipstenu/Development/repositories/site1-genesis: /vagrant/content/themes/site1-genesis
        /Users/ipstenu/Development/repositories/site2-genesis: /vagrant/content/themes/site2-genesis
        /Users/ipstenu/Development/repositories/site2-underscores: /vagrant/content/themes/site2-underscores
        /Users/ipstenu/Development/repositories/site1-plugin: /vagrant/content/plugins/site1-plugin
        /Users/ipstenu/Development/repositories/site2-plugin: /vagrant/content/plugins/site2-plugin
        #/Users/ipstenu/Development/repositories/site-mu-plugins: /vagrant/content/mu-plugins
        /Users/ipstenu/Development/repositories/site-mu-plugins: /vagrant/wp/wp-content/mu-plugins
    

    Run a reload and a provision of vagrant and it all worked. That’s right, it was all silently symlinked and had full access to all my code in all the right places… Except…

    Mostly Ugly Plugins

    You may notice this:

        #/Users/ipstenu/Development/repositories/site-mu-plugins: /vagrant/content/mu-plugins
        /Users/ipstenu/Development/repositories/site-mu-plugins: /vagrant/wp/wp-content/mu-plugins
    

    The first one didn’t work. The second one did, but only when I added this to my local-config.php file:

    define( 'WPMU_PLUGIN_DIR', '/vagrant/wp/wp-content/mu-plugins' );
    define( 'WPMU_PLUGIN_URL', $_SERVER['HTTP_HOST'] . '/wp-content/mu-plugins' );
    

    I’m still not sure if I broke it or if they did. What I do know is that I can rather easily build out my dev server, point it to my dev code, and everything’s working.

    Conclusion: Should you use Chassis?

    I firmly hold that all developers should be familiar with the shell. Maybe they’re not all golden goddesses, but they should know how to get around, list files, and Google the basic commands like links, rsync, move, copy, and delete. With that in mind, if you’re a developer (be it a code developer, a design developer, or anyone else who peeks under the cover at the code), you should give Chassis a try.

    It’s open source, so you can learn from it if you’re so inclined. It’s command line, so you can script it if you’re so inclined. You can separate your plugins from the plugins of the extensions, like debugging, and you can write your own if you want.

    Basically yes, you should use Chassis. It won’t be everything to everyone, but it can be something for most people.