Half-Elf on Tech

Thoughts From a Professional Lesbian

Author: Ipstenu (Mika Epstein)

  • A Sample Block: Spoilers

    A Sample Block: Spoilers

    Before I jump into this, I have to say .. this post was not written in Gutenberg.

    Sadly the plugin I use for code display, when I need it to be colored and easy to read, isn’t yet Gutenberg friendly. And, worse IMO, there’s a bug that causes multiline shortcodes to be smashed into one line, which makes a code block unusable. My two fixes are either the plugin I use be updated (which is beyond my skills at the moment) or I find a new plugin (looking). Or I wait.

    Anyway.

    Let’s make a simple block that you can’t edit!

    There are Four Files Needed

    1. spoilers.php – This is the main PHP file
    2. spoilers/index.js – This is the code
    3. spoilers/editor.css – This formats what you see on the editor
    4. spoilers/style.css – This formats what you see on the front end

    The last two aren’t required but I use them to make things pretty.

    The PHP

    The PHP file will need to be included in your code however you want to do it. I have a file called _blocks.php which includes all my Gutenblocks. In turn, it is included in my plugin’s main file.

    function lp_spoilers_block_init() {
    	$dir = dirname( __FILE__ );
    
    	$index_js = 'spoilers/index.js';
    	wp_register_script(
    		'spoilers-block-editor',
    		plugins_url( $index_js, __FILE__ ),
    		array( 'wp-blocks', 'wp-i18n', 'wp-element' ),
    		filemtime( "$dir/$index_js" )
    	);
    
    	$editor_css = 'spoilers/editor.css';
    	wp_register_style(
    		'spoilers-block-editor',
    		plugins_url( $editor_css, __FILE__ ),
    		array( 'wp-blocks' ),
    		filemtime( "$dir/$editor_css" )
    	);
    
    	$style_css = 'spoilers/style.css';
    	wp_register_style(
    		'spoilers-block',
    		plugins_url( $style_css, __FILE__ ),
    		array( 'wp-blocks' ),
    		filemtime( "$dir/$style_css" )
    	);
    
    	register_block_type( 'library/spoilers', array(
    		'editor_script' => 'spoilers-block-editor',
    		'editor_style'  => 'spoilers-block-editor',
    		'style'         => 'spoilers-block',
    	) );
    }
    add_action( 'init', 'lp_spoilers_block_init' );
    

    The JS

    Here’s the weird stuff. And I’m going to be honest here … I don’t understand all of this yet. But I picked this very simple example because it lets you see what’s going on in a concrete way.

    ( function( wp ) {
    	var registerBlockType = wp.blocks.registerBlockType;
    	var el = wp.element.createElement;
    	var __ = wp.i18n.__;
    
    	registerBlockType( 'library/spoilers', {
    
    		title: __( 'Spoiler Warning' ),
    		icon: 'vault',
    		category: 'widgets',
    		supportHTML: false,
    
    		edit: function( props ) {
    			return el(
    				'div',
    				{ className: props.className },
    				__( 'Warning: This post contains spoilers!' )
    			);
    		},
    
    		save: function() {
    			return el(
    				'div',
    				{ className: 'alert alert-danger'},
    				__( 'Warning: This post contains spoilers!' )
    			);
    		}
    	} );
    } )(
    	window.wp
    );
    

    The CSS

    There are two CSS files.

    editor.css

    .wp-block-library-spoilers {
    	border: 1px dotted #f00;
    	background-color: pink;
    	font-weight: bold;
    }
    

    style.css

    .wp-block-library-spoilers {
    	font-weight: bold;
    }
    

    Back in the js there was a bit that looked like this: { className: props.className },

    That’s what tells it to use these. In addition, I use this to call some theme specific code: { className: 'alert alert-danger'},

    The Output

    On the editor, I see this:

    Example of what the spoiler text looks like on the editor

    I included the block icon so you could see the little vault I used to indicate the block.

    On the front end, everyone sees this:

    A nice looking spoiler warning

    What’s Next?

    Making it editable, of course!

  • When You Need Blocks

    When You Need Blocks

    There are a lot of cases where you don’t need a custom block. My spoiler block (from last week) is a great example of that:

    But. What about when you want to have that spoiler have choices? Now you’re outside the shared content block territory and into the confusing land of Gutenberg plugins.

    Blocks Are Not Simple

    I’m the sort of person who abhors boilerplate plugins. I just do. I feel that they divorce you from understanding what the code is and does, and how it all plays together. The more you rely on them, the less you can debug when it goes sideways. Oh, and it will. It always does.

    But. Gutenberg requires a lot more Javascript than I happen to be good at. Or rather, it requires new Javascript. Which is why I did exactly what I did the first time I ever made any plugin. I went and found one that did mostly what I wanted, and I edited it.

    Whaaaaat? 

    It’s true. And I want everyone to take a moment and realize this is a perfectly normal, okay, thing! In fact, I would like to see Hello Dolly converted to include a Gutenblock because learning by example is a valid, tried and true, way to teach someone how things come together.

    What Examples Are Good?

    Okay so where is a good place to start?

    That’s enough to get you started, I think. I went with WP-CLI since I like it and I’m used to it. Of course, it came with a small problem. In order to make a block via wp-cli, you have to put the code in a plugin (or a theme). Well fine. I did that to scaffold it and then I moved it to where I was developing. Most people aren’t so particular.

    Is It Hard?

    Not really. Once you get used to editing the js file instead of PHP, it’s just like hacking any other plugin. Start with the simple thing. Make a block that just does one thing and isn’t editable. My one tip is that when you call your blocks, make sure to wrap it in a check if the function exists:

    if ( function_exists( 'register_block_type' ) ) {
    	include_once( dirname( __FILE__ ) . '/spoilers.php' );
    }

    Otherwise there’s a chance that a non-Gutensite will die on you.

    Good luck and happy Gutenberging!

  • Facebook to Automation: Nuts

    Facebook to Automation: Nuts

    Massive hat tip to Amanda Rush for pointing this out to me.

    Facebook is dropping support for apps to publish. I quote their recent post on policy updates:

    The publish_actions permission will be deprecated. This permission granted apps access to publish posts to Facebook as the logged in user. Apps created from today onwards will not have access to this permission. Apps created before today that have been previously approved to request publish_actions can continue to do so until August 1, 2018. No further apps will be approved to use publish_actions via app review. Developers currently utilizing publish_actions are encouraged to switch to Facebook’s Share dialogs for webiOS and Android.

    What is a Publish Action?

    Facebook uses actions to do ‘things’ within Facebook itself. A publish action is, logically, an action that triggers a publish of a post. When you create a Facebook app, you grant it special permissions to do specific actions, in order to prevent people from posting to your Facebook feed when they shouldn’t. If you’ve ever seen one of those popups like this, Facebook is asking you to confirm permissions:

    Screen asking to connect an app to your facebook account

    Most common are things that read content, like your posts and your friends, and so on. A publish_action would be like having your WordPress site automatically make a post on Facebook when you publish a post on your blog.

    Why Are They Doing This?

    The argument is that Facebook is maturing and “taking user privacy seriously” because the majority of people never read what permissions they’re granting, or who they’re going to be spamming with the cross posts. The reality? They’re locking down Facebook so if you want to get traffic from Facebook and your articles, you have to manually post them.

    Now. I hate artificial (and real) monopolies as much as the next nerd, and I do think this is a really cretinous move. But at the same time, by preventing auto-posting, they actually now have a way to combat fake news.

    If you watch The Good Fight, then you may have seen an episode where a bot script auto-generated posts, purporting to be someone, using fake news sites that people spun up. In season one, that was used to discredit Maia on Twitter. In season two, they took it to Facebook and demonstrated how the fake news sites could be used to target jurors and ensure they got the news.

    Seriously everyone needs to watch The Good Fight. They’re brilliant.

    But the point is this, by restricting people from auto-posting, then someone has to log in and make connections and it’s much easier to track behaviour. Facebook can block a VPN, but they can’t block Amazon AWS servers, after all. And those auto-posts are going to show as coming from your server, not your personal account.

    Do I Need to Care?

    Do you use Jetpack’s Publicize to post to your personal account? Then yes. Maybe. I don’t actually know what Jetpack’s going to do about this. My contact (i.e. my friend) just said they were on it, but I imagine there’s a lot of cursing in the background.

    Now, notice how I said personal account? And maybe?

    I noticed that Buffer, an app that auto-posts tweets and Facebook posts, said they’d be fine. On the other hand, Bridgely said they’re killing off their Facebook publish because of this. And on Facebook’s documentation for the APIs, the post to personal timelines information is gone, but the post to pages is still there.

    Which means I have no idea how horrible this will be. An incomplete block means spammers and fake reporters will move to posting to pages, which many users can post to. I can’t see how that will move the needle very far at all.

    Overall, I hate this and I think it’s a good thing.

  • You Don’t Need a Block

    You Don’t Need a Block

    Like a great many people, I recognize the need to learn the new world with Gutenberg and adapt my code as well as my writing to the platform. But, like a great many people, I recognized my coding ability might not quite be up to snuff with the javascript required for blocks.

    But then I asked myself something important. And you should ask yourself this, before you lament about how much work you have ahead.

    Do I need a new block?

    What’s a Block Anyway?

    The concept of ‘block’ writing is one people who use Scrivner may be familiar with. Or maybe if you’ve ever been a part of a writer’s room, breaking down a season of a TV show. The idea is that each index card is it’s own entity.’ Or rather, in the case of WordPress, each paragraph is it’s own entity.

    This means you can move the paragraphs around, which for paragraphs makes little sense. But for layout? Oh it makes a great deal more sense. A block is, literally, a block you move around until your page looks the way you want it to. Awesome.

    Why Don’t We Need Them?

    Actually the question should be when don’t we need them? Obviously we need blocks. That won’t change. But by default WordPress has quite a number of blocks out of the … block. And that begs the question of when and why do we need to make new ones?

    This is a question many developers who have shortcode plugins will be asking themselves, and the realization I stumbled across at WordCamp San Diego is that … a lot of developers don’t need to make new blocks! Because a lot of shortcodes aren’t actually going to be all that necessary in the future.

    Let’s use an example of something common…

    Example Shortcode: Spoilers

    Let’s say you have a WordPress site and it sometimes talks about spoilers.

    River Song warning the Doctor about Spoilers

    Today in WordPress an easy way to put a warning at the top of every page would be with a shortcode that looks like [spoilers] or if you’re feeling puckish, [spoilers warning="OMG SPIDERS!!!"] 

    Those would output a simple paragraph that warned people about spoilers.

    Right away, I thought “Oh, that would be a nice, easy sort of thing to turn into a block.” It’s just a direct output of some code:

    <div class="alert alert-danger" role="alert"><strong>' . $warning . '</strong></div>

    But then I thought …. What if I don’t?

    Enter Shared Blocks

    Shared Blocks, formerly called reusable blocks, are blocks of content defined by each site, specific to the site, that are .. well .. reusable. You don’t need to know how to code to make them, either. Which means you don’t need a developer to do this. Start by just making a new block with the content:

    Warning: This post contains spoilers!

    That’s easy. But what we want is to apply color to it. And that can be done in a number of ways. The easiest would be to use the advanced section in the block editor and add an additional CSS Class of, in this case, alerts.

    But that isn’t the only way…. Because I can also make this:

    Whaaat? Total game changer!

    Gutenberg Blocks Are Editable

    In every single Gutenberg block you can change text and color to suit your needs. I edited that particular block and said I wanted the background to be one color, the next another, and I wanted the size to be Large. I’m aware the large size doesn’t show properly… I also told it how I wanted the block alightment to look:

    Example of a block being edited

    Okay, But Reusing?

    Don’t worry, I didn’t forget. When you hover over a block there are three vertical icons on the right indicating a menu. Click on the menu and you get options and one is to convert it to a shared block. Click on that, give it the name you want, and you’ve created a block!

    Shared Block
    The share icon in the lower right is how you know.

    And now, when you go to enter a new block, you click on the plus button on the left, click on ‘Shared,’ and you have this:

    Example of searching for a spoilers block

    What’s Missing?

    Right away you’ll notice you can’t edit the shared block without editing it for everyone. So if you made it “Aaaaaahhh! Spiders!!!!!” everything would change. And that’s not great for everyone. But for a lot of people who just want a simple, repeatable, notice or signature, this is just fine. 

    It won’t spare you having to convert some of your shortcodes to blocks, but it may make life easier for people who don’t want to have to use them in the first place. And that, I think, is a win.

  • AutoDeploy: Github to DreamObjects

    AutoDeploy: Github to DreamObjects

    There are a lot of things that Github makes easy. One of them is a great way to keep versions of data publicly accessible, trackable, and deployable.

    Well. Not so much that last one.

    Automated deployment with Github can be incredibly convoluted, twisted, and perplexing. If you don’t speak high geek, it’s worse. Thankfully there are services like Codeship that let you ship code, run tests, and more importantly, run some hefty commands.

    When the day came that I wanted to keep some JSON files on Github for version control, but deploy them to the cloud, I knew what to do. I was already doing a version of the process, in reverse, for my Remoteless SVG images, after all.

    Create Your Repository

    Now I’m using Github, but Codeship supports Bitbucket or Gitlab, so that’s also an option. Once you’ve made your repository, commit your code but don’t push anything yet! We have to make a couple decisions first.

    First: Branches.

    I have two philosophies of this. If I’m working on something like a plugin or a theme or an app that needs versioned releases, I’m going to name my branches REL_1.2.3 and so on. If, instead, I’m maintaining a theme or plugin for personal use, I have a development branch that I use for all normal dev work. I may spin up a special branch for some new feature, but it always goes into that dev branch first.

    Second: Deployments.

    The reason I use that branch system is that when I push to the dev branch, it pushes code to the dev server.

    Schnieder from One Day at a Time (2017) going 'Mind blown'
    Mind? Blown.

    Once you decide how you want your set up to deploy, and when, you’re ready to Ship That Code.

    Gettit? Right…

    Setup Codeship

    If you’ve never setup Codeship before, I explain how you do that in my post about Deploying from Github with Codeship. The special sauce here is your Custom Script.

    Before you write the script, add in Environment Variables for AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY with those names specifically. This way you won’t have to write a mess of custom code.

    pip install 
    awscli aws s3 --endpoint-url https://objects-us-east-1.dream.io sync ~/clone/ s3://bucket-name/

    The important bits:

    • Endpoint URL is my S3-esque host
    • bucket-name is my bucket name…

    Push Your Code

    Once that’s saved, you can push code and it’ll automatically kick the code to the cloud.

    A lot of this is obviously a backwards implementation of code I already described, but sometimes we need something explained in the straightforward way to help us move forward.

    Enjoy your deploys!

  • Posts by Day, Every Year

    Posts by Day, Every Year

    In my previous post I mentioned a site that has a tag for a date. That is, it uses 25-march (or march-25) to tag it’s posts so someone could conceivably find all the posts made on March 25th in every single year.

    WordPress makes it easy to list all the posts on a specific date. Just visit example.com/2018/04/19/ and you’ll see all the posts made on April 19th of this year. Remove the 19 and you get everything from April and so on and so forth.

    But you can’t, out of the box, list everything on April 19th from every single year the site’s been up.

    WP_Query has Dates

    As of 3.7, WordPress has a date_query aspect to WP_Query which lets you do this:

    $all_posts_on_this_date = new WP_Query( array(
        'posts_per_page' => -1, // this will show all the posts
        'date_query' => array(
            array(
                'month' => date( 'n', current_time( 'timestamp' ) ),
                'day'   => date( 'j', current_time( 'timestamp' ) )
            ),
        ),
    ) );
    

    That generates an array of every single post that has the same month and day of today, but does not check the year. If you don’t want all the posts, just the last ten, use 'posts_per_page' => 10, instead.

    Once you have your list of posts, you can use a normal loop to display the content:

    if ( $all_posts_on_this_date->have_posts() ){
        while( $all_posts_on_this_date->have_posts() ) {
            $all_posts_on_this_date->the_post();
            the_title();
        }
    }