Test event with show attendees

Sunday December 22, 2019 7:00 PM

RSVP deadline is past


RSVP Form:Default

Guest ###

(+) Add more guests


RSVP Form:Default

Guest ###

(+) Add more guests


Web Development

Creating Wrappers, Sidebars, Callouts and Other Formatting Flourishes with WordPress Gutenberg

As the author of several WordPress plugins, I initially encountered the new Gutenberg editor that became standard in WordPress 5.0 as a disruptive change I had to scramble to adapt to. Since then, I have grown to appreciate it for significantly expanding what you can do with WordPress, particularly in terms of creating custom content formats to support your own uses of the platform.

The new editor model is organized around blocks of content: paragraphs, headings, bullet lists, images, and embedded videos are all blocks, and the editor displays different formatting options depending on the content type. It’s also possible for blocks to be defined with InnerBlocks, meaning that you are allowed to embed other blocks inside them. For example, the new Columns block lets you format content in two or more columns of equal width, and each column can include multiple paragraphs, images, and so on.

In addition, blocks can be programmed to act like WordPress shortcodes — placeholders for dynamic content that requires server-side processing. I’ve used that technique in the event listings block for my RSVPMaker plugin. In this post, though, I’m focusing on formatting of ordinary content.

Some parts of the new WordPress editing experience still need improvement, but I’m encouraged by the pace at which enhancements to the core platform have been arriving. If the content formatting controls delivered as part of the base platform don’t quite meet your needs, there are a few ways you can achieve the effects you desire:

  • Take advantage of plugins that provide a libraries of additional formatting blocks, enhancing both how you work in the editor and what visitors see on your site.
  • Take advantage of the Additional CSS Class field you will find in the Advanced tab of every block to tag a specific block of content. Use the Customize utility’s Additional CSS tab to provide additional formatting commands targeting that content.
  • Create your own Gutenberg plugins, as I’ve done with Floating Callout and My Marginalia, to meet your own needs or those of clients.

I share examples of each of these below.

Gutenberg Block Collections

Although I’ve created plugins that enable a single custom block to address a specific need, some talented interactive designers have created collections of components to meet common requirements. One of the best I’ve found so far is Editor Blocks by Danny Cooper, which includes some nice components for formatting team member or product description tables —

Team Members block from the Editor Blocks collection

— plus a nice wrapper or container block that allows you to specify margins, padding, and a background color or image to wrap around any content, including one of their other components.

The Wrapper Block from Editor Blocks sets the background image for the Pricing Table from the same collection.
Keynote Public Speaking Social Collaboration Social Collaboration for Dummies Social Media Team Messaging Video

“Unified or Fragmented” Keynote at Digital Collaboration 2017 in Stockholm

This speech updates themes from my Social Collaboration for Dummies book (Wiley, 2013). Since the book was published, team messaging tools such as Slack have begun to generate much more excitement, investment, and competitive energy than the enterprise social networking platforms I was writing about at that time.

At IDG’s Digital Collaboration 2017 conference in Stockholm, I discussed this trend in the context of efforts to unify multiple modes of communication and collaboration in one platform versus the trend toward rapid proliferation of specialized workplace tools — and the opportunities to create unified experiences out of diverse tools.


How to Post a Blog-Style Article on LinkedIn

I believe in the value of having a blog built into a business website, but there is also undeniable value in taking advantage of the publishing opportunities built into a couple of social networking sites: LinkedIn and Medium.

When you blog on your own site, you are enriching your site with content, giving visitors more insight into your business and business philosophy, and boosting your site’s search engine optimization score. In other words, you are trying to bring people to you and give them something to read when they come to you.

When you post on LinkedIn or Medium, you are going where the people are — or at least a rich concentration of people you might want to reach. These two approaches can work together, where you post something on LinkedIn or Medium that links back to your site’s blog or other content on your own site.

LinkedIn is particularly interesting for reaching an audience of people who are trying to get a new job or advance in their profession. I wrote this post partly as a guide for a friend who is starting a professional coaching business.

Because LinkedIn has been around since 2002 and most people know it as the social network stocked with interactive resumes and people sending “I would like to add you to my professional network” messages to each other, not everyone knows that it now essentially contains a blogging platform that is available to them.

As of the redesign that arrived in late 2016, here is where you find the blogging function at the top of the LinkedIn home screen:

LinkedIn article link
Link to “write an article”

You still have the option of writing a quick status post, which can optionally include a link, a photo, and one or more references to other users (type the @ symbol followed by the first few letters of the person’s name to get LinkedIn to search your contacts). This is useful for sharing something that would be interesting to people in your network, without taking the time to write an essay about it.

LinkedIn status post

When you click “write an article,” you instead get taken to a full screen editor that allows you to write a headline and the body of a post, with typical word processing controls for marking something bold or italic or adding bullets or numbered lists. If you copy and paste from Microsoft Word or another word processor, the formatting should translate fairly well (check it over carefully for any formatting or alignment glitches you might need to correct).

LinkedIn encourages you to add a large feature photo or image to be associated with your post, which you do by clicking the region at the top of the editor (the gray box with the + sign and image icons).

LinkedIn article editor

You can also add photos, video, and other media in the body of a post.

Much like the WordPress editor, the LinkedIn editor makes it relatively simple to add embedded media such as YouTube videos. Just paste in the url (web address) for an individual video on a blank line, and the video player will be added automatically.

Or you can click on this little icon in the left margin to display this row of media insert controls:

LinkedIn image and media insert controls

When you publish one of these articles, it is highlighted more prominently in the LinkedIn notifications scheme than if you had published a simple status post. A new article from someone in your network shows up in the same stream of notifications where LinkedIn shows that someone else has interacted with your profile or your content.

A notification of an article posted by someone in my network

Your latest LinkedIn post is also prominently displayed on your profile, along with your other most recent activity on the network.

A recent LinkedIn post and other activity displayed on my profile


One thing to be careful about is posting the identical content multiple places. For SEO, it’s better to drive all traffic to a single version of an article at a single web address. However, if you publish something on LinkedIn that you would also like to share on your own blog, you can do so without the SEO penalty if you remember to set the LinkedIn version as the canonical version of the article. See this explanation from the creators of the Yoast SEO plugin for WordPress.

Like all of social media, the LinkedIn publishing capability is something to explored in a spirit of experimentation. Find out what works for you and draws a positive reaction from your network.

Web Development

The Professional Power of Public Speaking (webinar replay)

Here is a replay of my YouTube Live event with Donald Kelly, Toastmasters District 47 pubic speaking champion, sponsored by PwC Digital.

Web Development

Fixing WordPress Paragraph Spacing (When the Visual Editor Misleads You)

A client of mine who blogs with WordPress ran into an issue with new posts appearing on her site without the proper spacing between paragraphs. I’m sharing the solution in case others might find it useful.

Everything looked fine in the WordPress visual editor, but these posts looked wrong on the public website. I thought at first it was problem with the site theme / CSS, but older posts on the same site were displaying fine. The only way to figure out what was going wrong was to view these posts with the editor toggled from Visual to Text to reveal some code that shouldn’t have been there. Every paragraph was tagged as a div — which in HTML is a block of text with no default styling. Also, an empty div is not displayed at all, so the blank lines she thought she had in her copy disappeared on the public site.

I suspect the divs got in there because this content had been copied and pasted from some other source, probably some other web-based word processor or blog posting system. WordPress usually does a pretty good job of handling content posted in from Microsoft Word, but not necessarily other sources.

Post with excess divs
Post with excess divs

In visual mode, WordPress identified all these divs as paragraphs, by the way, which was not helpful. Once you have paragraphs tagged as divs, WordPress keeps tagging any additional content you insert the same way.

To fix the posts, I had to manually remove the <div> and </div> tags. What a WordPress post normally looks like in the editor is a mix of text and HTML (for links and images) with a blank line between paragraphs. WordPress normally handles these formatting chores automatically — it just doesn’t handle an attack of the divs very well.

Properly formatted post in the WordPress editor.
Properly formatted post in the WordPress editor.
Presentations Public Speaking Toastmasters Video

Speech Video: The Internet of Things

David F. Carr: “The Internet of Things”

A public speaking sample from Club Awesome Toastmasters

Web Development

Notifier for Glip, a new WordPress plugin

This plugin will post a notification to a Glip team conversation whenever a new blog article is posted or a comment is posted to a blog that you maintain. The plugin uses the WebHooks interface to connect with Glip, the team collaboration and productivity platform from RingCentral.

The plugin is available through the WordPress.org plugins repository: https://wordpress.org/plugins/notifier-for-glip/

I do editorial consulting for Glip, so this came about because I was trying to cook up an example of using their support for WebHooks (a standard web services API). Commented code included below.

Target audience for this plugin:

  • Anyone who runs a WordPress website with multiple contributors and people posting comments.
  • Web developers and designers who need to keep tabs on a client’s blog posts and comment activity.
WordPress new blog post and comment activity, as recorded in the stream of comments in a Glip team conversation.
WordPress new blog post and comment activity, as recorded in the stream of comments in a Glip team conversation.

How It Works

The WordPress admin must set the WebHooks url for Glip on the Settings -> Glip screen.

Here is where you obtain that information from within Glip, after activating the WebHooks integration.

Glip WebHooks integration screen
Glip WebHooks integration screen

The plugin uses WordPress action hooks to detect new posts and comments and relay them to Glip in the JSON format specified above.

Here is the code I used for the initial release:

Plugin Name: Notifier for Glip
Plugin URI: http://www.carrcommunications.com/notifier-for-glip/
Description: Post a notification to a Glip team conversation whenever a new blog article is posted or a comment is posted to a blog that you maintain. The plugin uses the WebHooks interface to connect with Glip, the team collaboration and productivity platform from RingCentral.
Author: David F. Carr
Version: 0.9
Author URI: http://www.carrcommunications.com

function glip_webhook($webhook_url,$title, $body, $activity,$icon ='' ) {

$json = json_encode(array('icon'=>$icon,'activity'=>$activity,'title'=>$title,'body'=>$body) );

$ch = curl_init($webhook_url);                                                                     
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");                                                                     
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);                                                                  
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);                                                                      
curl_setopt($ch, CURLOPT_HTTPHEADER, array(                                                                          
    'Content-Type: application/json',                                                                                
    'Content-Length: ' . strlen($json))                                                          
$r = curl_exec($ch);
return $r;

function glip_post_published_notification( $ID, $post, $update ) {
	if ($post->post_date != $post->post_modified)
		return; // don't do this for edits to a previously published post
	$webhook_url = get_option('glip_webhook'); 
		return; // won't work without it
    $author = $post->post_author; /* Post author ID. */
    $name = get_the_author_meta( 'display_name', $author );
    $email = get_the_author_meta( 'user_email', $author );
    $title = $post->post_title;
    $permalink = get_permalink( $ID );
    $edit = get_edit_post_link( $ID, '' );
	$start = substr(strip_tags($post->post_content),0,100);
	$title = $update.sprintf('New post to blog: [%s](%s) by %s %s',$title, $permalink,$name,$email);
	$body = sprintf('%s


	$icon = plugins_url('wordpress-logo-32-blue.png',__FILE__);
	$activity = 'New Blog Post';
	glip_webhook($webhook_url,$title, $body, $activity,$icon);
add_action( 'publish_post', 'glip_post_published_notification', 10, 2 );


function glip_comment_inserted($comment_id, $comment_object) {

	$webhook_url = get_option('glip_webhook'); 
		return; // won't work without it

	$permalink = get_permalink($comment_object->comment_post_ID);
	$title = sprintf('New comment on blog by %s %s',$comment_object->comment_author, $comment_object->comment_author_email);
	$body = sprintf('%s
	Post: [%s](%s)',$_SERVER['SERVER_NAME'],$comment_object->comment_content,get_the_title($comment_object->comment_post_ID),$permalink);
	$icon = plugins_url('wordpress-logo-32-blue.png',__FILE__);
	$activity = 'New Comment on Blog';
	glip_webhook($webhook_url,$title, $body, $activity,$icon);

add_action('admin_init', 'glip_options_init' );
add_action('admin_menu', 'glip_options_add_page');

// Init plugin options to white list our options
function glip_options_init(){
	register_setting( 'glip_webhook_options', 'glip_webhook', 'glip_options_validate' );

// Add menu page
function glip_options_add_page() {
	add_options_page('Glip', 'Glip', 'manage_options', 'glip_options', 'glip_options_do_page');

// Draw the menu page itself
function glip_options_do_page() {
<div class="wrap">
		<h2>Glip Options</h2>
		<form method="post" action="options.php">
			<?php settings_fields('glip_webhook_options'); ?>
			<?php $webhook = get_option('glip_webhook'); ?>
       WebHooks address:     <input name="glip_webhook" id="glip_webhook"value="<?php echo $webhook?>" />
			<p class="submit">
			<input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
		<p>You will find this web address in the settings screen for the WebHooks integration, which is included with every Glip account. A menu in the upper right hand corner allows you to change the team conversation updates will be posted to.</p>

<p><img src="<?php echo plugins_url('glip-webhooks.png',__FILE__); ?>" width="580" height="372" alt="Webhooks" /></p>


// Sanitize and validate input.
function glip_options_validate($input) {

	if (!filter_var($input, FILTER_VALIDATE_URL) === false) {
		return $input;
	} else {
		return '';


function glip_admin_notice () {
$w = get_option('glip_webhook');
if(empty ($w) )
	printf('<div class="error">%s <a href="%s">%s</a></div>',__('WebHooks URL must be set for ','glipnotifier'),admin_url('options-general.php?page=glip_options'), __('Glip integration','glipnotifier'));

add_action('admin_notices', 'glip_admin_notice');