My Calendar Admin Notice

Admin Notice: The showkey, shownav, showjump, and toggle shortcode attributes have been deprecated. Use above and below instead.

If you’ve recently upgraded My Calendar to version 2.2.0, you may be seeing this notice at the top of your public calendar. This is because I’ve introduced a change in version 2.2.0, and although those four shortcode attributes will continue to work for now, I do intend to remove them completely down the road — so I need people to stop using them sooner rather than later.

The notice is only displayed for logged-in administrators – but it is possible that if you’re using a caching plug-in that the caching plug-in could pick this up; so it’s not impossible for it to be shown to the public.

To make it as easy as possible to switch, I’m going to explain right here (for those who do a search on this error message), what they need to do.

If you’re seeing the message, it means that the shortcode that’s producing your calendar uses one or more of these shortcode attributes:

  • showkey (controls the category key)
  • shownav (controls the previous/next navigation)
  • showjump (controls the quick navigation jumpbox)
  • toggle (controls the list/grid format toggle)

Rather than require a separate attribute to control each of these features, I’ve introduced two simple new attributes: above and below. With these shortcodes, you simply define which fields you want to see, in which position. This gives much greater control — you can now have your previous/next navigation both above and below if you want. You can place the format toggle before the navigation, or after.

Both new attributes support seven values, used as a comma-separated string. The replacement attributes for the original four are:

  • nav (turns on prev/next navigation)
  • toggle (turns on format toggle)
  • jump (turns on quick navigation)
  • key (turns on category key)

There are also three new attributes, configuring additional features:

  • timeframe (toggles to switch between month, week, and day)
  • print (turn on the print view link)
  • feeds (turn on the RSS and iCal feed links

Some of these features — in particular the print view and the feed links — will only show up if they have also been enabled in settings.

Hope that’s helpful!

Update to My Calendar: version 2.2.0

After over 3 months since my last release in the 2.1 series for My Calendar, I’m finally ready to release the next version of My Calendar. There are a lot of changes in this new version — and I think they represent some distinct improvements.

The complete list of changes can be seen in the Change log. That document goes through every change of substance I made. However, some of the more key items include:

  • Basic event search: It’s not complicated, but it sets the stage for future updates.
  • Simple integration with WP to Twitter
  • Time frame toggle: switch your view between month, week, and day view.
  • Variable recurrence schemes: No more “weekly or biweekly” — events happening every 3 weeks or every 6 months are equally supported.
  • Set the order of regions above or below the calendar: No longer just turning nav on or off; now, you can set whether nav is above or below the calendar, whether it’s before or after the jumpbox, etc.
  • aria-live support for AJAX navigation
  • Many other changes and bug fixes!

It’s been a long haul with a lot of testing, but I’m sure it’s not 100% bug free. Find something? Let me know!

Using a shortcode to fetch WordPress plug-in information

I may have a low threshold for managing information, but I find that with seven plug-ins in the WordPress repository it’s a struggle to keep my local information on those plug-ins always up to date. I have a page here about each plug-in, and it’s not uncommon that I’ll publish an update and go to check my local information just to find that my own page on that plug-in is six months out of date…

One way to keep that information nicely in sync is to actually import it directly from the WordPress plug-in repository’s information API. The API documentation is available, if you want to roll your own, but here’s a very basic bit of code to grab it yourself.

Creating a shortcode in WordPress is crazy-easy:


add_shortcode( 'plugin', 'get_plugin' );
function get_plugin( $atts ) {
    extract(shortcode_atts(array(
        'slug'=>''
      ), $atts));
    if ( $slug ) return show_plugin_info( $slug );
}

Woo hoo! You have a shortcode. This shortcode takes one attribute, “slug”, which will be the plug-in slug as seen in the repository. Now, technically speaking, what you have right now is a fatal error, because we haven’t actually defined the ‘show_plugin_info’ function. Fair enough — let’s do that.


function show_plugin_info( $slug ) {
    $body = (object) array( 'slug' => $slug );
    $post_data = array('action' => 'plugin_information', 'request' => serialize($body));
    $return = wp_remote_post( 'http://api.wordpress.org/plugins/info/1.0/', array( 'body' => $post_data ) );
    $plugin = unserialize($return['body']);	
    $return = "
            <p>Current Version: $plugin->version<br />
            Requires: $plugin->requires<br />
            Tested to: $plugin->tested<br />
            Downloads: ".number_format($plugin->downloaded)."<br />
            Last updated: $plugin->last_updated</p>";
    return $return . wpautop($plugin->sections['description']);
}

This is a pretty simple bit of scripting -- and, practically speaking, it's customized to show what I actually do on my own site. You may not want to even use this much code!

I'm using the WordPress wrapper for http requests to get the data -- this is much more reliable than using something like cURL or fopen, because the wrapper will query whatever transport is actually available, rather than depending on the specific wrapper you've defined.

The API is looking for very simple information -- just the slug for the plug-in, and the knowledge that we're accessing the plugin_information API.

With that, we retrieve an object containing all the basic information for the plug-in, largely drawn from the plug-in's readme.txt file. I've only chosen to incorporate a few fields into my site - but you can also grab several other fields this way. These fields are detailed at Dion's API information site, so I won't repeat them here.

This is a very basic shortcode -- simply place [plugin slug='wp-accessibility'] in your post or page and you'll get all the information about the plug-in you referenced.

Not sure how many other people are likely to find this useful...but for my purposes, it's pretty handy.

Speaking at WordCamp MSP on April 27th

It’s official – I’ll be speaking at WordCamp Minneapolis 2013 on April 27th, talking about WordPress and Accessibility. Speaking locally is pretty rare for me, so I’m really looking forward to meeting some other local WordPress people at the event. Oh, and the learning. That, too. :)

The official description of my talk, in the ‘Continuing Education’ track, is:

Covers a wide range of accessibility topics including but not limited to implementing best practice accessibility in theme building, discussing current progress and goals from the WordPress Accessibility P2 group, and address general principles of accessibility that might be of interest to WP developers and designers.

The organizers of the WordCamp are still setting up their speaker matrix, so I don’t yet know yet what my target audience will be — so this is a good time to think about who wants to learn!

Integrating Accessibility with WordPress is a broad topic — and the description reflects it. Are you attending WordCamp Minneapolis (just say yes) and have something you really want to know? Let me know in the comments or via Twitter! I’m listening!

WordCamp Minneapolis 2013
April 27th
Minneapolis Community & Technical College
1501 Hennepin Ave,
Minneapolis, MN 55403

WP Accessibility version 1.2.0 now available!

The new version of WP Accessibility has just been released. Updates include the inclusion of Chris Rodriguez’s a11y toolbar, as previously announced and support for a custom WordPress administrative stylesheet.

The first item, the accessibility toolbar, falls into a category of accessibility I rarely pursue: the front-end accessibility widget. I’ve written (negatively) about the concept before, in my article When More is Less. Having previously opposed accessibility widgets, I wanted to talk a little about why I think including this one is a good idea.

The Problem of Accessibility Widgets

The problem with accessibility widgets is that they are not an optimal solution. If the problem is that the text on your site is too small, then the optimal solution is to make the text larger. Providing a widget so that your users can make the text larger is clearly not the best possible solution.

But my WP Accessibility plug-in is in no way an “optimal” solution. While some of the elements of the plug-in involve creating an easier way of incorporating standard accessibility methods into a WordPress site, others are really about inserting improved accessibility into a site which is otherwise sadly lacking.

Don’t get me wrong: because WP Accessibility fixes some issues in the WordPress core code, it’s valuable in any WordPress site. However, a lot of the additional use cases for the plug-in are about patching accessibility into a site because the skill, time, or budget required to do it natively in the theme is lacking.

This is where the accessibility toolbar comes in. It may not be the best option for a site — but it may be the only realistic option.

If I may hypothesize a scenario:

You’ve just been hired by a company to manage their web site, after a previous developer left. They recently spent many thousands of dollars developing a new web site — but they didn’t really consider accessibility in the process. A complete revamp of the site isn’t something they have the budget or desire to engage on, but convincing them to install a plug-in that will have very little visual impact but improve accessibility is an easy target.

This accessibility toolbar is well designed – Chris did a great job. It’s subtle, simple, straightforward. I’m glad to be able to incorporate it.

WordPress Admin styles

Including a custom admin stylesheet allows me to fix a few minor issues in the accessibility of the WordPress back-end. Among these are some contrast changes; moving the post actions (Edit, Trash, etc.) into a context that’s visible to screen reader and keyboard users, underlining navigation links on hover, etc. What I’ve implemented is very basic, however — if anybody wants to extend them, they can do this by adding their own custom wp-admin stylesheet into their theme directory.

Custom WordPress Screen Options

For my next (still forthcoming) version of my WordPress calendar plugin, My Calendar, I had a need to add custom screen options to a couple of editing screens. Now, there’s a great tutorial on adding screen options by Chris Marslender that I found very useful.

It is, however, incomplete.

Now, if what you want to do is add one basic control, that tutorial is definitely going to get you where you need to go. It’s simple, straightforward, and accurate. However, it has one tiny error and one large omission.

The tiny error is simple: for saving the option, the tutorial specifies this code:


add_filter('set-screen-option', 'cmi_set_option', 10, 3);
 
function cmi_set_option($status, $option, $value) {
    if ( 'cmi_movies_per_page' == $option ) return $value;
}

This will work, for a single field. But, if you add two, you’ll notice that this filter *prevents* any other screen option value from being sent if it is not equal to ‘cmi_movies_per_page’. It doesn’t stop any of the default screen options, which are all whitelisted in the WordPress function handling updating options. When you add another custom function, however…no go.

Easy fix:


add_filter('set-screen-option', 'cmi_set_option', 10, 3);
 
function cmi_set_option($status, $option, $value) {
    return $value;
}

Because the value being returned by the function named is very simple; just an integer; there’s no need to filter it in any way; just make sure it gets passed to the function and then saved in the user’s meta data.

Adding custom controls to Screen Options

That was the error. The omission (which is entirely fair, because it was already a long tutorial — no need to cover everything!) is about adding custom controls and saving their data. Because, in fact, you can add any control to the screen options — you’re not constrained to the standard control types that WordPress uses.

For consistency, I’m basing my settings on the same type of data used in Chris’s tutorial; I think this will make it easier to compare the two tutorials and make use of them together.

First, getting some fields into your screen options. This can be ignored when using the default screen options, because they’ll provide your HTML controls for you. But you can attach your own custom controls through the filter screen_settings.


add_filter('screen_settings', 'cmi_show_screen_options', 10, 2 );

The function itself needs to do a handful of things:

  1. Define what it will return, whether it’s the desired screen or not.
  2. Determine whether it’s on the right screen for the controls.
  3. Return the form fields (the form itself is automatic)

The form fields must include an array of inputs named wp_screen_options[option] and wp_screen_options[value], or the submission will be ignored. As you’ll see further along, the option parameter is the important one; you need value to be present, but you don’t necessarily need to use it. That’s a choice, however, depending on what you’re doing with the data.

The current screen is passed to the screen settings function in an object variable of arguments, here called ‘$args’. You can test against your current screen using the $args->base member.


function cmi_show_screen_options( $status, $args ) {
    $return = '';
        if ( $args->base == 'toplevel_page_my-calendar' ) {    
            $button = get_submit_button( __( 'Apply' ), 'button', 'screen-options-apply', false );
            $return = "
            <fieldset>
            <legend>Show Columns</legend>
            <div class='metabox-prefs'>
            <div><input type='hidden' name='wp_screen_options[option]' value='cmi_show_columns' /></div>
            <div><input type='hidden' name='wp_screen_options[value]' value='yes' /></div>
            <div class='cmi_custom_fields'>
                <label for='cmi_producer'><input type='checkbox' value='on' name='cmi_columns[]' id='cmi_producer' /> Producer</label>
                <label for='cmi_director'><input type='checkbox' value='on' name='cmi_columns[]' id='cmi_director' /> Director</label>
            </div>
            </div>
            </fieldset>
            <br class='clear'>
            $button";
        }
        return $return;
}

In this example, I’m passing data using an arbitrarily named field called cmi_columns. I’m hypothesizing this as a group of controls to limit which fields you’re showing on a plug-in page.

Saving your Custom Screen Options

You’ll be using the same filter as in the other tutorial to save your data:


add_filter('set-screen-option', 'cmi_set_screen_options', 11, 3);

In the function itself, you can manipulate the POST data sent from your custom screen options however you wish. You can dance with it, change it, ignore it; whatever is relevant for you. If you need to interpret the data sent and use it in a way other than that directly posted, here’s where you can do it. Not in this example, however — which simply takes the posted data, and returns it to be saved in the user data.


function cmi_set_screen_options($status, $option, $value) {
	if ( 'cmi_show_columns' == $option ) { 
		$value = $_POST['cmi_columns'];
	}
	return $value;
}

That’s it. Value saved and passed.

What’s important in this tutorial?

If you’re trying to use the information from Chris’s tutorial to create multiple screen options, you’re going to get a little frustrated when the second one just won’t save. That’s because of the failure to return a value in the filter unless the specific field is passed. If you need to pass a type of data other than defaults, that tutorial doesn’t cover it. So here you are. Enjoy!

Smart Tweeting with WP to Twitter

WP to Twitter is a time-saving tool for sharing your WordPress-composed content with your Twitter followers. But creating a smart Tweet is different from authoring great content: when you’ve only got 140 characters, you’ll want to think strategically.

There’s always a compromise between saving time and authoring something unique. The maximum in time savings comes from using the template tools in WP to Twitter to generate the text of every Tweet. An effective formula using your post title, your URL, and some tags is simple enough.

But what if you want to do something different? Now you’re into customization.

Writing a smart Tweet is about effective use of language: appealing to your followers with the fewest words you can.

Short Tweets are effective — they allow for easy sharing and re-tweeting; long tweets mean that either your Tweet must be shared using the Twitter “ReTweet” feature or the user needs to edit your copy in order to share your Tweet.

Hashtags are useful, so it’s worthwhile to include at least one. A hashtag creates an avenue for people to view your Tweet because they’re monitoring that hashtag. It’s absolutely valuable to reach the audience that is topically interested in your content but may not already be following you!

Your URL is obviously a crucial element, to send readers back to your site.

But what else?

People like to add their own commentary to Tweets when they share them – it may be nothing more than “This is cool: “, but when there’s room for those 14 characters, the likelihood that your Tweet will gain traction is noticeably higher.

There’s an interesting article at Social Media Today about re-Tweeting: Crafting the most Re-Tweetable Tweet You Can, by Charles McGuinness. In that article, the author demonstrates that there is an inverse relationship between re-Tweets and the length of Tweets: the longer the Tweet, the less it is re-Tweeted.

Over about 36 characters, the re-Tweet frequency levels out, with a spike of higher re-Tweeting at 120 characters.

Now, given that if you’re using WP to Twitter one of your goals is to share your web site content, keeping your Tweets under 36 characters is probably not at all realistic. Once you’ve got 20 characters for a URL, you only have 16 characters left for a title. That’s the word “self-sacrificing”, and I don’t think that’s what you need to be in this case…. So, not a lot of space.

But that spike at 120 characters is interesting. It’s a sharp and decisive spike – right back up to the popularity of a 24-28 character Tweet.

So what’s the value of maximizing that 140 characters? Do you gain anything by fitting in a couple extra words? In a word, I think…no. You just don’t. Your Tweet has a little more information in it (assuming that keeping information density high and leaving out anything extraneous), but it’s a little less likely to be shared — and it’ll reach fewer people.

So, what’s an ideal Tweet?

  • 120 characters or less
  • Links back to your content
  • Includes one hashtag, maybe two if they’re really relevant.

I could set the character limit at 120 characters in WP to Twitter – but, honestly, that’s just getting pedantic. You’ve got 140 characters, and you’re free to use them. But I recommend against it.

SO, I can hear you asking, why are there so many options for customization in WP to Twitter? Well, that’s all about special cases: you may want to include a reference to another author. You may need to reference an alternate URL. You may need to add extra tags. It’s great to have lots of options: but smart usage is knowing that you don’t always want to use them.

References:

Page 1 of 5123Last

Return to Top