Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: embed

  • Saving Theme Data to a File

    Saving Theme Data to a File

    Your life isn’t all WordPress.

    I know, I know, I said a dirty thing, but let’s be honest, everything isn’t always all WordPress. And when that happens, you have to do some weird things to make your data shared.

    One of the things I needed one day was a way for non-WordPress files to get access to a theme setting. See, the theme let me set a top-bar and customize it. Sometimes I did that to share news, sometimes to link to latest posts. Regardless, I updated it via Customizer, and it worked great for WordPress.

    Not so much for my static HTML site, or my non-WordPress PHP site.

    I dwelled on it for a while and then thought “Wait, if the theme knows how to echo a specific setting, then there has to be a function for that. And if there’s a function, then can’t I hook into Customizer saving to trigger the creation of an HTML file with the data and call that from my other sites?”

    And guess what? You can!

    The WordPress Code

    Toss this in an MU Plugin and it’ll save a file to wp-content/top-bar.html when you save customizer settings.

    <?php
    class HELF_Top_Bar {
    
    
    	public function __construct() {
    		add_action( 'customize_save_after', array( $this, 'save_top_file' ) );
    	}
    
    
    	/**
    	 * Safe the top file
    	 * When customizer is saved, copy the get_theme_mod() data and parse it
    	 * into a file: wp-content/top-bar.html
    	 * @return n/a
    	 */
    	public function save_top_file() {
    		$default     = 'Something Default Here';
    		$banner_text = get_theme_mod( 'top-banner-text', $default );
    
    		$fp = fopen( WP_CONTENT_DIR . '/top-bar.html', 'w' );
    		fwrite( $fp, $banner_text );
    		fclose( $fp );
    
    	}
    
    }
    
    new HELF_Top_Bar();
    
    

    The Javascript

    The what?

    For my other PHP file, it’s a simple file_get_contents() call to the HTML. But for static HTML I had to resort to trickery with Javascript.

    <script>
    	var elem = document.getElementById("wpcontent");
    
    fetch('https://example.com/wp-content/top-bar.html', {
            credentials: 'include'
        })
            .then(function (response) {
                return response.text();
            })
            .then(function (text) {
                console.log('Request successful', text.length);
    			console.log('Request successful2', text);
    			$('.wpcontent').html(text);
            })
            .catch(function (error) {
                console.log('Request failed', error)
            });
    </script>
    
    <div class="wpcontent"></div>
    
    

    And magic happens.

  • NoEmbed: Embedding What’s Not oEmbed

    NoEmbed: Embedding What’s Not oEmbed

    We all love oEmbed with WordPress. Want to include a YouTube video? Paste in the URL and call it a day!

    The magic is that WordPress sends data to the YouTube oembed endpoint (i.e. a special app on YouTube that translates URLs to embed things) and says “Hi, I have this video URL here, what can I use to embed it?” And YouTube replies back “This javascript, my fine friend!” WordPress tips it hat and carries on, swapping the URL out for javascript on the fly.

    Awesome.

    Except when it doesn’t work because it can’t because there isn’t an oEmbed endpoint.

    What Now?

    Usually I make a shortcode. But my man Otto always grumbles and tells me to make an embed instead.

    The concept of the embed is that we register a ‘fake’ oembed. It’s not an endpoint, it’s just saying “Hey, WordPress. When you see this kind of URL all alone, let’s make magic.”

    It’s surprisingly straightforward. All we need to know are two things:

    1. What is the URL people are going to paste in?
    2. What is the output supposed to look like?

    Since we’ve already done this as a shortcode, we’re ready to go.

    Register the Handler

    First we have to tell it that we’re making a new handler, called indiegogo and this is the kind of URL to expect:

    wp_embed_register_handler( 'indiegogo', '#https?://www\.indiegogo\.com/projects/.*#i', 'indiegogo_embed_handler' );
    

    The first part, indiegogo, is the name. It should be unique.

    The second part, '#https?://www\.indiegogo\.com/projects/.*#i' is saying “http OR https” and “as long as the URL starts with www.indigogo.com/projects” — it’s ‘basic’ regex.

    The last bit, indiegogo_embed_handler is the function name we’re going to need.

    Write the Embed Function

    This is very similar to the shortcode. We take the data, make sure it’s formatted correctly, and output the (in this case) iFrame:

    function indiegogo_embed_handler( $matches, $attr, $url, $rawattr ) {
    	$url   = esc_url( $matches[0] );
    	$url   = rtrim( $url, "#/");
    	$url   = str_replace( 'projects/', 'project/', $url );
    	$embed = sprintf( '<iframe src="%1$s/embedded" width="222" height="445" frameborder="0" scrolling="no"></iframe>', $url );
    	return apply_filters( 'indiegogo_embed', $embed, $matches, $attr, $url, $rawattr );
    }
    

    I’ve left the filters in place in case I decide I want to do more weird things to it, without having to edit the core part of my code.

    A GutenGotcha

    For some reason, this doesn’t work in Gutenberg, and it tells me it cannot embed the content. Except when you visit the page, everything is embedded perfectly.

  • Indiegogo Embed

    Indiegogo Embed

    Indiegogo doesn't have oEmbed, which means you can't just paste in a URL and expect it to work on a WordPress site. And worse, their directions are "Use an iframe plugin!"

    NO.

    Just say NO to iframe plugins!

    Use a shortcode instead!

    If you're brand new to shortcodes, check out Sal Ferrarello's awesome post about it (I saw him talk at WC Philly 2017 and he's amazing). I'll give you the highlights for this one code though.

    The Code

    /*
     * Embed an IndieGoGo Campaign
     *
     * Usage: [indiegogo url="https://www.indiegogo.com/projects/riley-parra-season-2-lgbt"]
     *
     * Attributes:
     *		url: The URL of the project
     */
    add_shortcode( 'indigogo', 'helf_indiegogo' );
    function helf_indiegogo() {
    	$attr = shortcode_atts( array(
    		'url' => '',
    	), $atts );
    	
    	$url    = esc_url( $attr['url'] );
    	$url    = rtrim( $url, "#/");
    	$url    = str_replace( 'projects/', 'project/', $url );
    	$return =  '<iframe src="' . $url . '/embedded" width="222px" height="445px" frameborder="0" scrolling="no"></iframe>';
    
    	return $return;
    }
    

    What It Does

    The code is as basic as I could made it, and it takes the URL of the campaign, strips out the trailing hashtag, changes projects to project (singular – and yes, that gave me a headache), and punts out an iframe.

    Thankfully they make this easy unlike places like CrowdRise where you have to magically know the ID number in order to pull this off.