Back End Instructions – official release
So, you might remember, back in August, I wrote a plugin called “Back End Instructions” and popped it on my site for you all to freely download and use, if you wanted. If you recall, the plugin is for those of you who have a lot of clients that utilize WordPress, and you’ve written a custom theme for them, but no matter how many times you send instructions or answer their questions on how to use it, they still keep asking you.
I’ve discovered that the reason clients do this is because (and no offense to clients – we live in an “instant gratification” age right now) it’s easier to just call you and ask when they forget how to do something than search for the last time they asked you and you provided that answer. You can send them written instructions or answer their questions with meaningful subject lines in email (so it’s easy to find), but they’ll still just call you when they forget instead of looking to see if the question’s already been answered. They want something that’s right there, in their face, and they don’t have to go looking for it.
So I came up with this plugin, and I tell ya, it’s been a lifesaver. It’s very unobtrusive, but there when you need it. basically, it uses the Custom Post Type functionality of WordPress to display instructions on any page you want within the administrative end of the WordPress installation. Not only can you create posts for each individual page of the site, you can customize said instructions so they only show for certain user levels – so people with “Contributor” levels won’t see the extra info that applies to Admins.
You can use written instructions, audio, video – anything you like. It’s just like writing a regular post – the only difference is it shows up in the back end of the site.
I’m getting ready to plop this into the WordPress Plugin Repository for people to download and utilize, but I figured I’d go ahead and write a little sumthin’ sumthin’ here on my site about it, so that’s in place when people have any questions.
Now, please note, this is the most intensive plugin I’ve ever written, and I’m not 100% sure how the whole “upgrade notification” thing works. I dont’ know if the WordPress system just suddenly tells you that a new version is available for download, or if I have to put in special code for that to happen. I’ve never quite found a 100% assurance on the issue, so I’ve given up and I’m just going to try it and see.
Back End Instructions
Tested in WordPress 3.0.x – 3.1.2
initial indications show that it also works in MU mode – but this isn’t fully tested.
if you downloaded the plugin back in August and have been using it, then I will ask you now: please download this new version, an you might have to FTP into your system and see if you have 2 copies. I’ve renamed the folders and such so many times since my last iteration that it’s probably best if you just delete the old plugin files, and grab these new copies and put them in. (Don’t worry, your already-existing instructions won’t be touched – they’ll still be there.)
There’s an extensive readme file in the download that will most likely answer any questions you might have – so I’m not going to copy the whole thing here. Instead, I’ll give you the highlights and some basic instructions, and let you run off with the readme file for the more in-depth stuff.
So, after you’ve installed and activated the plugin, you’ll see a new menu item show up to the left side, called “Instructions”. When you go there, there’ll actually already be a new post, and when you look to the top, there’s a new little tab on the page that says “View Instructions for this page”. Click it, and you’ll see this quick little video:
That gives you a quick run-down of how it all works. But what I didn’t mention in the video (sorry, it took me something like 15 tries to get that one done. I’m not doing it again LOL) was that if you’re not using self-hosted, YouTube or Vimeo for the instructions, you can just use the regular post content area and pop the videos in there. For example, if you go to WordPress.tv and find a video you’d like to have your client see, you can just click the “Share” link (in the upper left-hand corner) choose the HTML code” and paste it into the content area. As long as the “Video URL” field is blank, it won’t overwrite what’s in the regular content area, and you can still see the video. Just be sure you’re in HTML-writing format, because if you’re in “Visual” it’ll strip the code and it won’t work properly.
Please, if you have any questions, or have some idea on how I can improve this, pass it along. I really want this to be useful for people
Enjoy!
Adding in changelog info. I never thought to do this before, so I’m just gonna start with the one I just uploaded – version 0.8.
0.8 I’ve fixed the issue where you can’t make the instruction show up on a specific page. Now you can make it show up on a “general” page or a specific one. For instance, if you want the instruction to show up on ALL “add new post” pages, you just pop in “post-new.php”, and the instruction will appear on any of them. But if you want a specific page, then look in your url and add everything after the last “/”.
I’ve had many requests to make the stylesheet easier to control, and not make upgrading overwrite your changes without saving. Now you can. Just create a file (“bei_style.css”) and pop it into your theme directory, at the same level as the style.css file. You can style as you wish without worrying about things getting overwritten.
Now you don’t need an additional plugin to his the menu item from lower levels. Administrators and Editors will be able to see the menu item in the sidebar, but lower levels will not. (If you’d like it to be Admins only, easy fix – but remember, upgrades will change any edits you make): in bei_post_type.php, line 13, change if(current_user_can('edit_others_posts')) to any of the admin capabilities here (for example, if(current_user_can('update_core')) will swap it to Admins only).
For future releases, I’m considering creating an administrative settings page that allows you to set your stylesheet and choose what the lowest level is to view the menu, but for now I’m not sure that’s really all that important. I’m also working on a version that stops relying on Jing, and uses HTML5 Video instead – then you have more options to play your videos instead of being stuck with Vimeo, YouTube or SWF files.
New Plugin: Back End Instructions
Well hello there!
I’m all excited. I think I’ve mentioned before (although for the life of me I can’t find reference to it) that I wrote a quick plugin once to provide back end instructions for clients. It was using the Userextra/Usermeta plugins, and I edited/added text right in the plugin area to pull up the right stuff, so it wasn’t easily managed. It worked (and was a “quick fix”) – but I wanted it to be better.
My dream was to have it really easy for an administrator to manage, edit and remove instructions for clients. Bonus points for allowing video and/or audio content.
I finally pulled it off
So this plugin basically uses the new custom post types functionality that WP provides. It installs a new type, and you simply go in, write a post, tell it what page to show up in, and publish. There’s custom fields that you can use for various things – but in essence, it’s writing a post via WordPress that will publish in the back-end instead of the front. It uses jQuery so it “slides open” on demand to reveal the “instructables”, and on pages that don’t have instructions, there’s no indication of the plugin at all.
Now, this is not quite ready for an official release. Right now, I’m after testers to help me find and squish bugs. So if you’d like to download this and give it shot (and let me know how it goes for you) I’d really appreciate that.
You can download the files here: Back End Instructions for WordPress
Notes to go along with this:
I’m still working on the stylesheet – so some of the output looks weird at the moment.If your WP install is in a subdirectory, you won’t see it working properly (I know why – I just have to fix it). This will work for installs in the root of your site.- The only multimedia I’ve used with this is YouTube. I’d like to have other media tried – like vimeo, or
Jing(working for Jing – at least the SWF files anyway!) – and have audio files, etc. tried out and see how that goes. - I’m considering adding an admin page (or something) so you can easily uninstall this plugin. Deactivating it will still leave the content in your database, since it’s using native WordPress capabilities. I’m riding the fence on this, because in truth, all the plugin truly adds to your database is the little registration to let the system know it’s there. The rest is just posts – it’s just a custom post type. So if you deactivate the plugin, the posts/content remain, you just wont’ see them anymore. I’m leaning towards somehow changing the post type back to “post” so the content will show up in your regular post listing – because I keep thinking that people would want to remove the plugin, but keep the content. This is under debate – I’m not sure what the best way to handle it is.
So please, if you download this and try it out, please let me know how it goes! Thanks!
Update: 8/14/2010 I’ve actually been putting this to use today for a client’s site, and have found (and worked out) a few little bugs. I’m not finished, but I expect I’ll have the full plugin ready for serious scrutiny by Monday. I’ve finally checked the Jing capabilities, and even though the file you’re downloading right now doesn’t work with Jing, I’ve already gotten fixes in place that do. So watch for it on Monday!
Update: 8/16/2010 Okay, I’ve uploaded a new version this morning. I’m terrible, because I need to figure out how to let people know it’s been updated! I always forget to do that. But It’s now working with YouTube and Jing, but I’d still like to try it out on Vimeo and Blip.tv. I also worked out a bug/conflict that I ran into with Role Scoper, and I’ve edited it a bit so if you have role-specific instructions, it’ll hide them from lower-level users.
Update: 8/16/2010 @ 11:05 am Another update – the newest upload now contains internationalization, and I’ve cleaned up the code so the header stuff doesn’t get added to pages it doesn’t need to be added to. I’ve also added some commenting to make understanding the code better, and grouped certain functions into new files. Oh, and in the earlier update this morning, I’d forogtten to add the necessary Jing files – whoops! They’re in there now.
Update: 9/1/2010 @ 3:32 pm Per request, you can now add instructions for the dashboard. I’ve also cleaned up and reorganized the file system, so be careful when you upload. (There’s a readme file in there – pay attention to it!)
Better Text Widget
NOTE: October 5, 2010
I just recently used this plugin while developing locally for a client. I did an SQL export of the site to move the testbed to the live server, and was muchly surprised to discover this widget does not get retained in the database for some reason. I had to redo all of the widgets manually.I just wanted to post notice of this bug, because I want you to know that I know, and I’m working to correct it.
Yes, I’ve been quiet for a few weeks. I’ve had some issues come up, and have been trying to knock them out of the park. I was just saying this morning, it amazes me how I’m on sabbatical, but I’m busier now than I was when I wasn’t! (OMG – that has to be some kind of grammatical nightmare right there.)
Anyway, recently I’ve had a lot of people around me (not directly to me, but sort of discussing around me) that they are using WordPress, but wished they’d had a widget that would pull off certain functionality. I can’t give you their exact words, but the gist of it is that they want some kind of easier-to-use text widget.

If you don’t know what I mean, basically WordPress has a default widget (that comes with the installation) that’s called “Text Widget”. The description of said widget is “Arbitrary text or HTML” So basically you can type up any text you want and shove it into a Widget. If you know a little HTML, you can put in an image, etc., but you would have to know the proper syntax to do it. Most of my clients look at HTML as if it’s Mandarin Chinese. However, using other widgets are overkill, and sometimes present “TMI” that they can’t seem to sort through. What they wanted was a Widget where they could put in text (or even just have an excerpt from a particular page or post), easily add an image, and even have the title of said widget look different than the title they name the widget.

Lucky for you all, I’ve already written one, and have been using it for some time. Over the last 3 weeks (or so) I’ve been handing out the code for it when anyone asks me for it. I was just getting ready to send it again, when it just dawned on my that DUH – that’s what my site is for. So here. Take it! Just pop this code into your functions.php file, and run
Update on July 12, 2010: I’ve been asked also to add in something to make the title of the widget be optionally hidden. It just so happens that I just finished doing exactly that for a client recently, so I’m adding in those lines.
Also – not because I was asked, but because I’ve found this addition very handy – is the option to make accessing the theme directory files easier. Many times, I’m developing on my own server and eventually I need to move the site to a client’s server. Many of the widgets have a full path coded, and those don’t change when you move the site, so stuff ends up broken. I’ve edited the code to make that a whole lot easier.)
$home = get_bloginfo('home');
$templatedir = get_bloginfo('template_url');
$uploadsdir = wp_upload_dir();
$uploadsdir = $uploadsdir['baseurl'];
$imgdir = $templatedir . '/images'; // be sure to change the directory to whatever you've named your images directory within your themes folder
add_action( 'widgets_init', 'easier_text_widgets' );
function easier_text_widgets() {
register_widget( 'Easier_Text_Widget' );
}
class Easier_Text_Widget extends WP_Widget {
function Easier_Text_Widget() {
$widget_ops = array( 'classname' => 'easier_text_widget', 'description' => __('Similar to the plain-vanilla "Text", but makes it easier to manipulate without the need to know PHP or HTML.', 'easier_text_widget') );
$control_ops = array( 'width' => 300, 'height' => 350, 'id_base' => 'easier-widget' );
$this->WP_Widget( 'easier-widget', __('Easier Text Widget', 'easier_text'), $widget_ops, $control_ops );
}
function widget( $args, $instance ) {
global $post, $imgdir, $uploadsdir, $templatedir, $home;
extract( $args );
$title = apply_filters('widget_title', $instance['title'] );
$hide = $instance['hide'];
$image = $instance['image'];
$link = $instance['link'];
$link_text = $instance['link_text'];
$id = $instance['id'];
$text = $instance['text'];
// replace "home" with home url
$findimg = strpos($image, 'images');
$findhome = strpos($link, 'home');
$finduploads = strpos($image, 'uploads');
$findlinkuploads = strpos($image, 'uploads');
if($findimg !== false) $image = str_replace('images', $imgdir, $image);
if($finduploads !== false) $image = str_replace('uploads', $uploadsdir, $image);
if($findhome !== false) $link = str_replace('home', $home, $link);
if($findlinkuploads !== false) $link = str_replace('uploads', $uploadsdir, $link);
if($hide !== false) $class = 'class="hideme"';
else $class = '';
echo $before_widget;
if (!empty($link) && empty($image) && empty($link_text)) {
echo $before_title . '<a style="font-size:1.1em;" ' . $class . ' href="' . $link . '">';
if (!empty($title))
echo $title;
echo '</a>' . $after_title;
} else if(!empty($title)) {
if($class == '') echo $before_title . $title . $after_title;
}
if (!empty($image))
$img = '<img src="' . $image . '" alt="' . $link_text . '" />';
if (!empty($link)) {
echo '<a href="' . $link . '">';
if(!empty($image))
echo $img;
else if(!empty($link_text))
echo $link_text;
echo '</a>';
} else if(!empty($image)) {
echo $img;
}
if (!empty($id)) {
$excerpt = get_the_excerpt();
if($excerpt == '') {
$excerpt = get_post_meta($id, 'page_excerpt_value', true); // post meta value
}
echo '<p>' . $excerpt;
echo '<a class="more-link" href="' . get_permalink($id) . '"> more</a></p>';
}
if (!empty($text)) {
$findimg = strpos($text, 'images');
$findhome = strpos ($text, 'home');
$finduploads = strpos($text, 'uploads');
if($findimg !== false) $text = str_replace('images', $imgdir, $text);
if($findhome !== false) $text = str_replace('home', $home, $text);
if($finduploads !== false) $text = str_replace('uploads', $uploadsdir, $text);
apply_filters( 'widget_text', $instance['text'] );
echo $instance['filter'] ? wpautop($text) : $text;
}
echo $after_widget;
}
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title'] );
$instance['hide'] = isset($new_instance['hide']);
$instance['image'] = strip_tags($new_instance['image']);
$instance['link'] = strip_tags($new_instance['link']);
$instance['link_text'] = strip_tags($new_instance['link_text']);
$instance['id'] = strip_tags($new_instance['id']);
//$instance['$text'] = stripslashes($new_instance['text']);
if ( current_user_can('unfiltered_html') )
$instance['text'] = $new_instance['text'];
else
$instance['text'] = wp_filter_post_kses( $new_instance['text'] );
$instance['filter'] = isset($new_instance['filter']);
return $instance;
}
function form( $instance ) {
global $imgdir, $uploadsdir, $templatedir, $home;
$defaults = array( 'title' => __('', 'easier_text'),
'hide' => __('', 'easier_text'),
'image' => __('', 'easier_text') ,
'link' => __('', 'easier_text'),
'link_text' => __('', 'easier_text'),
'id' => __('', 'easier_text'),
'text' => __('', 'easier_text')
);
$instance = wp_parse_args( (array) $instance, $defaults ); ?>
<p><label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e('Title:', 'hybrid'); ?></label>
<input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" style="width:100%;" />
</p>
<p><input type="checkbox" id="<?php echo $this->get_field_id( 'hide' ); ?>" name="<?php echo $this->get_field_name( 'hide' ); ?>" <?php checked($instance['hide']); ?> />
<label for="<?php echo $this->get_field_id( 'hide' ); ?>"><?php _e('Visually hide title'); ?></label>
</p>
<p><small style="color:#777; font-style:italic;display:block;">If you'd like to use an image (that's not already within the content) in this widget, enter in the full path to the image. <br />
Use "<strong>images</strong>" instead of the full path for images located within the theme files. For example, "images/BG.jpg" will convert to "<?php echo $imgdir; ?>/BG.jpg. <br />
Use "<strong>uploads</strong>" for the path to the uploads directory, if using a media file image. This will give you the first part of the directory, but you will need to supply the rest of the path to the file - the year, month directories and image file name.")</small><label for="<?php echo $this->get_field_id( 'image' ); ?>"><?php _e('Image Path:', ''); ?></label>
<input id="<?php echo $this->get_field_id( 'image' ); ?>" name="<?php echo $this->get_field_name( 'image' ); ?>" value="<?php echo $instance['image']; ?>" />
<p><label for="<?php echo $this->get_field_id( 'link' ); ?>"><?php _e('Full URL to link image or text to - rules for paths apply as with images:', ''); ?></label>
<input id="<?php echo $this->get_field_id( 'link' ); ?>" name="<?php echo $this->get_field_name( 'link' ); ?>" value="<?php echo $instance['link']; ?>"/>
</p>
<p><label for="<?php echo $this->get_field_id( 'link_text' ); ?>"><?php _e('Link text (will also be used as the alternate text for the image):', ''); ?></label>
<input id="<?php echo $this->get_field_id( 'link_text' ); ?>" name="<?php echo $this->get_field_name( 'link_text' ); ?>" value="<?php echo $instance['link_text']; ?>" />
</p>
<p><label for="<?php echo $this->get_field_id( 'id' ); ?>"><?php _e('ID of Page or post you would like the excerpt from:', ''); ?></label>
<input id="<?php echo $this->get_field_id( 'id' ); ?>" name="<?php echo $this->get_field_name( 'id' ); ?>" value="<?php echo $instance['id']; ?>" />
</p>
<p><label for="<?php echo $this->get_field_id( 'text' ); ?>"><?php _e('If not using an excerpt, then enter in text you would like to display. HTML is allowed.', ''); ?></label>
<textarea class="widefat" rows="7" cols="20" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>"><?php echo $instance['text']; ?></textarea>
</p>
<p><input id="<?php echo $this->get_field_id('filter'); ?>" name="<?php echo $this->get_field_name('filter'); ?>" type="checkbox" <?php checked($instance['filter']); ?> /> <label for="<?php echo $this->get_field_id('filter'); ?>"><?php _e('Automatically add paragraphs.'); ?></label></p>
<?php
}
}
Creating an HTML signature file for just about anything
So I’ve recently had the opportunity to create a plethora of (pinatas?) e-mail siggy files
And not just a nice little siggy file to place with your Outlook or Mac Mail program, but in ALL KINDS of things. Even for Gmail.
I had to piece together the “how-to”s from a bunch of different sources throughout the web, but I’m here to share how I did it, and how I managed to make it work for all kinds of different mail-reading-and-sending programs.
read more »
Holy crap, I made a boo-boo!
I was just informed about a stupid mistake I made with my CakeShop plugin (formerly called “Simple Cart”). So please, if ANY of you have downloaded those files before today, redownload them NOW.
Here’s the reason why…
read more »
