An issue on a site leads to a solution that almost no one besides me can figure out, so we go at it again. Now there is happiness (infer).

One of the more confusing aspects of running WordPress as multi-site is the meaning of the role of Administrator. On a self-hosted single WordPress site, as the administrator, you are god-like. You can do anything, you can install themes & plugins, you can use any kind of HTML in your posts. That’s what people expect as having that role.

But in multisite, that god-like power is only for the Network Administrator(s) who also have the ability to add users across the system and create new sites. But as person who is an Administrator of a single site (not the Network Admin) you are more like a Junior Administrator– you can only enable plugins and themes the Network Admin has made available.

It’s really not the same role.

There is one more crucial frustrating limit. As a site / junior admin within a Multisite network, like anyone else (Editor, author), you are limited into what kind of HTML you can use in a post– you cannot include JavaScript, iframes, more or less any HTML based embed codes from other sites. These are what WordPress calls “unfiltered HTML” and are stripped out when a post is saved.

“But why? I am an administrator on my site?” users will (rightfully ask).

Well, Junior, you are actually not a full administrator.

The answer (and I am making some broad guesses) is security. The way multisite is developed seems to be for big networks where one copy of WordPress might be running hundreds, thousands of sites. Naked Javascript and embed codes are potentially sources of hacks that can be injected. If you are running that many sites, a hack on one affects them all.

What has often happened to me, is that as a network admin, I author a page/post with some Javascript or an iframe in it, publish, and it works. But maybe another user on the site who is an admin or en editor, spots a typo in the post (nothing related to the code I added), fixes it, and when they save it, the embeds or script code is borked– because it is stripped out.

You can find a wide range of ways around this, all seems a bit kind of hackish to me.

Not all multisite instances re designed for hosting blogs for a community; for many of my projects or sites such as ds106, it benefits from sharing themes, plugins, the user database for maybe 2-5 maybe 7 sites.

IMHO it would be nice as a person who sets up a multisite to choose whether to apply this limitation.

That’s the scene setting, now the plot. I lend a hand or two with the Virtually Connecting site, which until a few months ago, was a single site. When Rebecca Hogue asked about creating a second site for the ePatients arm of VC, using the same theme and plugins, it seemed to make sense at the time to convert the primary site to multisite (in hindsight I might have just added a second site, but you go 20/20 hindsight).

That went smoothly so we have one sister site http://epatients.virtuallyconnecting.org/.

We have a number of people who create blog posts for events, about 23 on the site, most are editor or author roles.

And now we get to the first problem I did not anticipate. For out live events we generate a World Time Buddy event widget:

sample Time Buddy Widget

I really like this thing, It presents the time of the event on top, and converts to the bottom one which represents the time on whatever zone a visitor is in (plus a nice countdown thing on the right).

An author for a post like the upcoming one for the Creative Commons Summit might add a few of these.

So an author goes to the World Time Buddy Events Widget maker, sets the time zone for where the conference is taking place, sets the start date and time….

Setting the World Time Buddy event widget options

… then they copy this embed code:



Time converter 
at worldtimebuddy.com

Now if I or another Network Admin uses this embed code, it looks fine. But if someone with a different author rule creates the post, or edits one of my numerous typos, when they save it, the embed code that worked for me disappears.

It confuses everybody in the mix.

So I decided to help.

One way around the limitations of unfiltered HTML is to create a WordPress shortcode, kind of like a way to tell a post or page when it is rendered to swap out a place holder for the embed code with the real real.

Looking at the embed code, the part that is needed is in the src=".." and actually just the part after .js?. My first effort to “help” people was tell them to generate the widget code at the Timebuddy site, and copy the part of that src=".." string as the value in the shortcode I made for params, or

[timebuddy params="h=6167865&md=4/28/2017&mt=14.50&ml=1.00&sts=0&sln=0&wt=ew-ltc"]

I did some testing, broke a few things, and then got it working. This is code I added to the theme’s functions.php (actually it is a child theme, always do child themes, always do child themes, always do child themes…):

/* ----- shortcode to time buddy widget -------- */
add_shortcode("timebuddy", "do_vc_timebuddy");  

function do_vc_timebuddy ( $atts ) {  

	// generate a Timebuddy widget because WP strips script tags
 	extract( shortcode_atts( array( "params" => ""), $atts ) );  
 	
 	if ( empty( $params ) ) {
 		return "Missing parameter! set params=\"xxxxx\" from the Timebuddy generated embed code for <code>src=\" e.g. params=\"h=2643743&md=2/24/2017&mt=19.50&ml=1.00&sts=0&sln=0&wt=ew-ltc\" after the \"?\"";
 	} else {
 	
 		return 'Time converter at worldtimebuddy.com';	
	}
}

I used it a few times and tried to explain in our Slack how to use my “neat” trick.

Everyone just nodded and just did it they way they did before. Yanking a part of a URL out of some HTML blobs was a bit steep for most humans.

So that idea lead to another. What works for people is copying the embed code from Time Buddy and pasting the whole shebang in the editor. My idea was to add a button to the WordPress editor that would pop open a dialog box, that someone could paste in the embed code, and I run some code that converts it to the shortcode.

I have done a few mods to the wordpress editor (called TinyMCE) for other projects, sometimes with a plugin. I poked around the internet and the best explanation for what I was doing came in a post from Gavick Pro (it actually did way more than I needed so I skipped a bunch.

I first had to figure out how to get the embed code in via Javascript and to yank out the part I needed for the shortcode, so I mocked up a real simple HTML test file:




	
	Timebuddy test
	




Enter the Timebuddy Widget Event code

With a bit of fiddling I got it to work.

Next, I went to figure out how to roll this into the WordPress interface, adding more or less a small plugin to the editor. In researching I found out that TinyMCE has it’s own built in pop up window manager that is cleaner than a standard Javascript prompt one.

This code goes into my WordPress child theme functions.php, it more or less tells WordPress to add a button to the editor.

/* ----- editor buttons for time buddy widget -------- */

add_action('admin_head', 'timebuddy_buttons');

function timebuddy_buttons() {
    add_filter( "mce_external_plugins", "timebuddy_add_buttons" );
    add_filter( 'mce_buttons', 'timebuddy_register_buttons' );
}
function timebuddy_add_buttons( $plugin_array ) {
    $plugin_array['timebuddy'] = get_stylesheet_directory_uri() . '/js/timebuddy_widget.js';
    return $plugin_array;
}
function timebuddy_register_buttons( $buttons ) {
    array_push( $buttons, 'timebuddy'); 
    return $buttons;
}

The real work is done in the Javascript code that sites in the js directory of the theme as timebuddy_widget.js:

(function() {
    tinymce.PluginManager.add('timebuddy', function( editor, url ) {
        editor.addButton( 'timebuddy', {
            text: 'TB',
            icon: false,
			onclick: function() {
				editor.windowManager.open( {
					title: 'World Timebuddy Event Widget',
					body: [{
						type: 'textbox',
						name: 'code',
						label: 'Paste Code'
					}],
					onsubmit: function( e ) {
					
						if ( e.data.code.indexOf('class="wtb-ew-v1"') !== -1) {
								pstart = e.data.code.indexOf('.js?') + 4;
								pend = e.data.code.indexOf('script>') - 4;								
								editor.insertContent( '[timebuddy params="' + e.data.code.substring(pstart, pend) + '"]');
						} else {
						
							editor.windowManager.alert('Sorry, that does not seem to be a valid Timebuddy Event Widget code.');
        					return false;
		
						}
					
					
					}
				});
			}            
            
        });
    });
})();

I could have gotten fancy and made the button an icon, but TB seems to work well.

Sooooo, now any author in the site can generate the Timebuddy Event Widget, copy the whole clump of HTML embed code. In the Virtually Connecting site, they click the TB button, and paste in that clump:

And when they click ok, they get the shortcode that will make the widget appear when published

And now it works more closely to the way people would expect it to.

That was a bit of a longish overview of what it took to add one little button. But as always, in going from one thing to another, I learned a few new tricks.

Now just to be clear, this is wired into my theme; I guess if I really had my stuff together, I would roll all of this int a plugin.

Maybe next week, I need to flip that record and hear the rest of The FIXX…


Featured image: 1983-05-09 ‘Reach The Beach’ by The Fixx [Japan JVC for U.S. MCA Records Pressing] flickr photo by Wishbook shared under a Creative Commons (BY-SA) license — cropped to emphasize the title of track 1. I remember a lot of these songs coming through the early years of MTV

If this kind of stuff has value, please support me by tossing a one time PayPal kibble or monthly on Patreon
Become a patron at Patreon!
Profile Picture for CogDog The Blog
An early 90s builder of web stuff and blogging Alan Levine barks at CogDogBlog.com on web storytelling (#ds106 #4life), photography, bending WordPress, and serendipity in the infinite internet river. He thinks it's weird to write about himself in the third person. And he is 100% into the Fediverse (or tells himself so) Tooting as @cogdog@cosocial.ca

Comments

  1. Hi Alan,
    I love reading this stuff.
    I’ve been trying out some tinymce stuff myself and getting quite confused. There does not seem to be a set of docs to edit the editor that is WP focused, although the post you found goes a fair way. Good to have more examples.

    We bump into the limitations of multisite in Glow Blogs quite frequently. Our developer has done a couple of interesting things, one, made some urls act like oemebeds (paste in a url). The other is to change an iframe block into a shortcode before the editor strips out the iframe which might be interesting to you.

    1. Thanks Tom, I keep your iframe one bookmarked somewhere. The decision is do you want to allow all script tags through? I’d rather spin our shortcodes for the things one wants to allow. That’s a question definitely when you are perched on 20,000 blogs. I might be more inclined to do it on a smaller multisite.

      All in all (and I should find the way to yell this into the WordPress engine)- their design for multisite is one dimensional, hosting many blogs, like you do. There are other modalities like my case where it seems one could relax the tightness of the chokehold.

Leave a Reply to john Cancel reply

Your email address will not be published. Required fields are marked *