WordPress Plugin Repository

So a looooong time ago, I released my first WordPress plugin – expandable jQuery comment replies. I’ve been remiss in keeping it updated – it was written for WP 2.7, and here we are, almost on 3.1. So when I released by Back End Instructions plugin, I decided perhaps I should be a good girl and update my old plugin.

Updating it locally wasn’t an issue. however, updating the repository…. that’s a different story.

I don’t use Terminal a lot, so it’s still a little bit alien to me. I’m not terrified of it anymore, but I still walk on eggshells when I use it – I don’t want to ruin anything. (My stuff, I don’t care so much about – it’s accidentally…I dunno – wiping out the entire plugins database that scares me! LOL) Although the first time I added a plugin wasn’t so difficult, like I said – it’s been a while, updating is another story.

There’s a nice codex page on the issue, but it doesn’t really dive into the whole thing. I think it was written more for people who are used to downloading the nightlies, and adding code and plugins like crazy all the time. The Codex page is more of a “quick overview” kind of thing.

So while it’s fresh in my mind, I’m going to share a few little tidbits that I’ve come to understand – so when I do this again I don’t have to spend three hours just trying to update something.

Adding a brand-spanking new plugin
First off – when you want to add a fresh, new plugin, you have to ask first. I don’t remember doing this before, so it must be a new thing they’ve added to help maintain quality control (which is a good thing). From what I’m reading, when you submit the form for adding a plugin, you’re basically notifying the WP team that you want to add a new plugin, and apparently they download your file and take a few days to actually check it out (I’m being told it’s anywhere between 3 to 10 days – for me it was pretty quick). Then they’ll send you an email and give you your SVN directory so you can add the files to the repository.

Once you get the go-ahead to submit the plugin, you need to shell into the system to add it.

Now, again, I use Terminal. I’m on a Mac, and it comes with this sweet little program already built in. I don’t know what you’d use for a PC, but I do recall needing to shell some stuff back when I was using one, and I had to find and download a program – my system didn’t had anything built in for it. (Again, this is based on an old lady’s memory.) So if you’re on a PC, you’ll have to find something that allows you to shell into the plugins server. The following instructions are Mac-based, but I believe shell access doesn’t care if you’re on a Mac or PC, so if you’ve got something that gives you access, these instructions should work for you.

So, using terminal, you basically open up the puppy, and you should be in your root directory (Macintosh HD/Users/your computer name). It’ll basically look – in the Terminal Window – like:

192: ~ somename$

and have a little square cursor next to it.

Now, you want to create a new directory to store all your stuff in. So you type in (for purposes of example, we’ll use the name “plugins”)

mkdir plugins

and hit “enter.” If you have a Finder window open, you’ll see a new directory being created there :)

Now you need to access your own little part of the Repository world. The directory name they gave you (we’ll say it’s “love-potion-9″ in acknowledgement of Valentine’s Day) is your address. So next, you need to type in:

svn co http://svn.wp-plugins.org/love-potion-9 plugins

And this basically “checks out” what is there. If this is a new plugin, most likely there won’t be anything but some empty folders (trunk/trunk, branches, tags), and everything in your little area will be downloaded to your new plugins” directory.

So now you want to copy the plugin files you have on your computer to the “trunk” directory of the stuff the SVN just added to your hard drive. DO NOT create a subdirectory, and DO NOT put in a zipped file. Just take all the files from the root level of your plugin and move them to the “trunk” of the new area.

Now, back to Terminal. You need to “speak” to the WP server and tell it you’re preparing to commit some stuff to the server. You have to let it know that there’s new stuff there. So you need to change the directory to your local plugin area

cd plugins/

and then you should see the beginning part change – instead of

192: ~ somename$

you should see

192: plugins somename$

that’ll tell you you’re in the right directory. (if you get an error that the directory doesn’t exist, type in cdand it should move up a level, then try again.)

Now you want to “speak” to the repository, and tell it to take the files that are in your local copy and copy them to the matching directory in the WordPress repository. You do this by typing in:

svn add trunk/*

This basically tells WP that you are in your “plugins” directory that matches theirs, and you want to take everything in your local “trunk” directory and copy it to the WordPress’ matching “trunk” directory. You’ll see the terminal window sort of pause for a few seconds, then this stuff will show up. The lines will begin with “A” (the WP server telling you it’s “added” the files) and then the curosr will appear again.

Once you’re satisfied that all the files are properly in their place, you want to commit this. (If you quit now, then everything you’ve done up to this point will go away.) So you type in:

svn ci -m 'Adding first version of my plugin'

And you’ll see a message that the files are transmitting, and finally it’ll give you a “committed revision” message. All done – you can close out. Usually, in no more than 15 minutes after this point – the new plugin will show up is the plugins repository. You can easily see it by looking at the “Newest” section. By the way, the “Adding first version of my plugin” thing can really be any message you want to have there.

Updating an existing plugin
This is where I ran into trouble – apparently adding is much easier than editing! (Well, not really, but it seemed like it LOL). Really, it’s very similar to adding a new plugin. You want to start by opening up Terminal, and making sure you’re in whatever directory you want on your hard drive (I like to do my stuff at the very root of my hard drive, so I don’t accidentally edit it at some point in the future) and log into the repository to “check out” the file system that’s living there, again by typing in:

svn co http://svn.wp-plugins.org/love-potion-9 plugins

NOTE: be aware that when you do this, if you’re in your local copy, it’ll overwrite what’s there. So if you’ve already made changes, I HIGHLY recommend that you rename your existing “trunk” folder to “trunkNEW” or something so your changes don’t get overwritten, and then move the files after you’ve checked out what’s on the WP server, so you don’t lose your changes.

This will basically copy the files in the repository to your hard drive (“checking out” – like at the library). You can then open up whatever files you want to edit (I HIGHLY recommend the readme.txt file and the root file so you can change the version number and add to your changelog. But the readme.txt file is the big one.) Once you’ve made your changes, simply save them, and change your directory in the terminal so you’re in your plugin area (if you haven’t already) and then type in:

snc ci -m 'Updating my plugin to version whatever'

and hit enter. it magically knows which files you’ve changed – you’ll see them list up and it’ll end with “Committed revision [some number]“. In a bit, you’ll see the version number of your plugin in the plugins area of WordPress.org change to the new version, and everyone will be magically alerted to the update.

Custom Write Panels for WordPress 3.0

NOTE: October 5, 2010
Just letting you know that for some reason, some of this custom post type info does not transfer well. I used this one a site recently, and through SQL exports, I’ve discovered that the information within *some* of these fields does not get retained in an SQL export, and when you move your site, you lose some fo the info. Now, I don’t know if that’s just something in MY theme files for the project I was doing, or if it’s something in these examples that causes information to go missing, but I’m just making you aware of the possibility.Most likely it’s the former, since this doesn’t happen to ALL of the custom fields, but only a few.

I just wanted to make you aware so if it happens to you, you’ll already know I know, and I’m trying to figure it out.

As promised (from earlier today) I’m going to supply a small tutorial. Over the last few weeks, I’ve actually been bombed with requests on how to do this, and I’ve been happily passing out my code to anyone who’s asked for it. (I think it’s because of this comment I left on Liam McKay’s site. I guess it piqued a lot of interest.)

I will also say that, earlier today, I mentioned that the tuorial he provides was tossing up errors for me – which it did – but as it turned out (in my checking of the code I’m about to give you) that it was *my fault* – not his. So I apologize for saying that before. His tutorial – as it stands, works just fine in WordPress 3.0. it was my fudging with it to make it work with different field types what was munging it.

That being said, I won’t rehash Liam’s entire tutorial. He covers the basics of what’s going on just fine. I don’t feel it’s necessary to reinvent the wheel there, so I’m not going to rehash all of that here.

However, I’ve had several projects where these panels come in very handy. But I wanted to use something other than text input to retain the values. In some cases, using a checkbox or radio button would work much better. Makes it a lot easier for the client, you know? In. 2.9.x, I had this working just fine*, but the shiny, new updated version made it slightly more difficult to pull off. but I did it, because i needed it. So I’m going to tell you how I did it so it’ll help you.

You know, because I’m good like that.


If you’d like to download the basic plugin that shows the whole shebang, you can click here and take a gander: Add Post Meta Files

So the point of this is to expand upon the genius that is the Custom Write Panels Tutorial. A couple of things I will note is when I’ve used this in the past, and I wanted to do one set of stuff for posts, and a different set for Pages… it just makes everything a lot easier to just use this as a plugin instead of plunked into your functions.php file. For me, anyway, trying that just made my functions.php file immensely huge, and I was always fighting with conflicts. So I’ve found it easier to manage to just make ‘em plugins. But feel free to do what you like!

Now I’m thinking I could just use the array values to decide what types of Pages or posts these shoudl go on… hmmm… I feel an experiment coming on…

So the changes I’ve made to Liam’s tutorial is fairly simple, really. It’s basically adding a little bit more to your arrays in the beginning, and adding some conditional statements and foreach loops. At the very beginning, we set up a “key” value (which is the meta_value that’s placed in the database so we can find it and use the information later), and then we begin our arrays for the fields. The original tutorial only sets up arrays for the name, title, description and other assorted stuff. What we are going to do is also set up the type of field we want for each item, and a couple of “aesthetic” array values so it doesn’t look weird.


$key = "key";
$meta_boxes = array(
"input" => array(
"name" => "input",
"title" => "Input Field",
"description" => "This is an example for a regular input field.",
"type" => "text",
"rows" => "",
"width" => "100%",
"options" => ""
),
"textarea" => array(
"name" => "textarea",
"title" => "Textarea Field",
"description" => "This is an example for a textarea field.",
"type" => "textarea",
"rows" => "6",
"width" => "100%",
"options" => ""
),
"checkbox" => array(
"name" => "checkbox",
"title" => "Checkbox Field",
"description" => "This is an example of a checkbox field.",
"type" => "checkbox",
"rows" => "",
"width" => "",
"options" => array("1" => "checkbox 1",
"2" => "checkbox 2",
"3" => "checkbox 3",
"4" => "checkbox 4",
"5" => "checkbox 5",
"6" => "checkbox 6")
),
"radio" => array(
"name" => "radio",
"title" => "Radio Field",
"description" => "This is an example of a radio field.",
"type" => "radio",
"rows" => "",
"width" => "",
"options" => array("1" => "radio 1",
"2" => "radio 2",
"3" => "radio 3",
"4" => "radio 4")
),
"dropdown" => array(
"name" => "dropdown",
"title" => "Dropdown Selection",
"description" => "This is an example of a dropdown field.",
"type" => "dropdown",
"rows" => "",
"width" => "",
"options" => array("1" => "option 1",
"2" => "option 2",
"3" => "option 3")
),
"checkbox2" => array(
"name" => "checkbox2",
"title" => "Checkbox Field",
"description" => "This is an example of a secondary checkbox field.",
"type" => "checkbox",
"rows" => "",
"width" => "",
"options" => array("1" => "yes")
)
);

You’ll notice I have two “checkbox” types here. That’s because I wanted to show you that you can re-use these arrays, and vary how they will be used. In the first one, we’ve got a bunch of checkboxes – but the last one would be more of a “yes/no” type deal. (Check for “yes”, unchecked for “no”.) but that one’s just used as an example – any of these fields can be reused.

Now, the only other area we need to change is in the display_meta_box() function. Namely in the “foreach” loop contained within. We’re changing Liam’s basic function from this:


<?php
function display_meta_box() {
global $post, $meta_boxes, $key;
?>

<div class="form-wrap">

<?php
wp_nonce_field( plugin_basename( __FILE__ ), $key . '_wpnonce', false, true );

foreach($meta_boxes as $meta_box) {
$data = get_post_meta($post->ID, $key, true);
?>
<div class="form-field form-required">
<label for="<?php echo $meta_box[ 'name' ]; ?>"><?php echo $meta_box[ 'title' ]; ?></label>
<input type="text" name="<?php echo $meta_box[ 'name' ]; ?>" value="<?php echo htmlspecialchars( $data[ $meta_box[ 'name' ] ] ); ?>" />
<p><?php echo $meta_box[ 'description' ]; ?></p>
</div>

<?php } ?>

</div>
<?php
}
?>

To an extremely huge and expanded form that makes me wish I’d get to it and install some sort of code-formatting plugin. In all honesty, the beginning of the code above stays the same – you only need to change right around the foreach loop – just after the wp_nonce_field call:


<?php
function display_meta_box() {
global $post, $meta_boxes, $key;
?>

<div class="form-wrap">

<?php
wp_nonce_field( plugin_basename( __FILE__ ), $key . '_wpnonce', false, true );

$output = '';
foreach($meta_boxes as $meta_box) {
$data = get_post_meta($post->ID, $key, true);

$output .= '<p style="font-size:1.1em; font-style:normal;">' . $meta_box['title'] . '<br />' . "\n";
$output .= $meta_box['description'] . '<br />' . "\n";

if($meta_box['type'] == 'text') { // plain text input
$output .= '<input type="text" name="' . $meta_box['name'] . '" value="' . $data[$meta_box['name']] . '" style="width:' . $meta_box['width'] . ';" />';
}

else if($meta_box['type'] == 'textarea') { // textarea box
$output .= '<textarea name="' . $meta_box['name'] . '" style="width:' . $meta_box['width'] . '; height:100px;">' . $data[$meta_box['name']] . '</textarea>';
}

else if(($meta_box['type'] == 'checkbox') && (!empty($meta_box['options']))) { // checkboxes
foreach($meta_box['options'] as $checkbox_value) {
if($data[$meta_box['name']] != "") { // if array is empty, warnings will be issued, this circumvents it
$output .= '<input type="checkbox" name="' . $meta_box['name'] . '[]" value="' . $checkbox_value . '" ' . (isset($data[$meta_box['name']]) && (in_array($checkbox_value, $data[$meta_box['name']])) ? ' checked="checked"' : '') . '/> ' . $checkbox_value . '   ' . "\n";
} else {
$output .= '<input type="checkbox" name="' . $meta_box['name'] . '[]" value="' . $checkbox_value . '"/> ' . $checkbox_value . '   ' . "\n";
}
}
}

else if(($meta_box['type'] == 'radio') && (!empty($meta_box['options']))) { // radio buttons

foreach($meta_box['options'] as $radio_value) {
$output .= '<input type="radio" name="' . $meta_box['name'] . '" value="' . $radio_value . '" ' . (isset($data[$meta_box['name']]) && ($data[$meta_box['name']] == $radio_value) ? ' checked="checked"' : '') . '/> ' . $radio_value . '   ' . "\n";
}
}

else if(($meta_box['type'] == 'dropdown') && (!empty($meta_box['options']))) { // dropdown lists

$output .= '<select name="' . $meta_box['name'] . '">' . "\n";
if (isset($data[$meta_box['name']])) {
$output .= '<option selected>'. $data[$meta_box['name']] .'</option>' . "\n";
}

$output .= '<option value="">----------------</option>' . "\n";
foreach($meta_box['options'] as $dropdown_key => $dropdown_value) {
$output .= '<option value="' . $dropdown_value . '">' . $dropdown_value . '</option>' . "\n";
}

$output .= '</select>' . "\n";
}

$output .= "</p>\n\n";
}

echo '<div>' . "\n" . $output . "\n" . '</div>' . "\n\n";

} ?>

That’s really pretty much all there is to it. I’ll explain the pertinent information in bits, just to break it down into a more palatable chunk of information (I know that looks like a lot up there!) We’ll start with the array information.

Setting up the arrays
Basically, this is the only section you’ll really need to edit. Since the “checkbox” field has the most information, I’ll use it as an example to explain what’s going on.

"checkbox" => array(
Obviously, this is the beginning. It’s basically just setting up your field with a name that will be associated with the values. Makes sense, right? The array is the stuff that makes up the field, so you can manipulate what’s going on.

"name" => "checkbox",
The “name” of the field within the array. It does *not* have to match the one above, but I find it helps. This one is required. Gotta have it!

"title" => "Checkbox Field",
Optional. This is the text that will appear in the custom panel, the label of the field.

"description" => "This is an example of a checkbox field.",
This is the optional description. If there’s some ‘splaining that needs to be done for this particular field, I’ll use the description for that purpose. You can leave it blank if you like.

"type" => "checkbox",
Required. Here’s where get into the meat of it. This field here tells the code what kind of input type you want. Standard names apply.

"rows" => "",
Optional. For use only when using the “textarea” type of input.

"width" => "",
Optional. This is if you so desire to apply a width value to the textarea and text input fields. I usually so desire, so it’s there.

"options" => array("1" => "checkbox 1",
"2" => "checkbox 2",
"3" => "checkbox 3",
"4" => "checkbox 4",
"5" => "checkbox 5",
"6" => "checkbox 6")
),

This is your secondary array for your options. This pupply is pretty useless for textareas and text fields, but for checkboxes, dropdowns and radio buttons,it’s really handy. You can change the numbers to more associative type stuff – that’s your preference. But the second part (“checkbox 1″, “checkbox 2″, etc) are what your values and text for the fields are (same text applies to both).

Really, that’s all you need to know. If you go messing with the other part, I won’t be held responsible. ;) But you can if you really feel the need to – I won’t come banging on your door to arrest you if you do!

Just so you know, you can assign where you want this stuff to show up. As it stands, it’ll show up in the “Write Post” area – which (as explained in the original tutorial) – is set in the create_meta_box() function (which is under the above-described array) in this line:

add_meta_box( 'new-meta-boxes', ucfirst( $key ) . ' Custom Post Options', 'display_meta_box', 'post', 'normal', 'high' );

You can have it assigned to Pages by changing it to this:

add_meta_box( 'new-meta-boxes', ucfirst( $key ) . ' Custom Post Options', 'display_meta_box', 'page', 'normal', 'high' );

or even – with the lovely new 3.0 feature of custom post types, assign it only to your custom post type. (in this example, we’ll say your custom post type is called “pictures”):

add_meta_box( 'new-meta-boxes', ucfirst( $key ) . ' Custom Post Options', 'display_meta_box', 'pictures', 'normal', 'high' );

Hopefully that helps you in your next project!

How to pull out the information
Silly me! i went and published this without telling you how to actually pull out this information and use it! That’s not very handy.

Unfortunately, I have to quickly make dinner (the kidlets are starving, apparently) so I will return shortly to tell you exactly how to do that.

Okay, so getting the info out and using it elsewhere is actually pretty simple. In the old version, you had to call every single item (because it wasn’t placed in a nice, neat array like it is now) via get_post_meta. If you had a lot of meat_key/meta_value pairs, that made for a lot of calls. But now, it’s one call (per key, as set in the top of the array), and you just pull them out with brackets.

So, within the Loop, you just need the single call:

<?php $fields = get_post_meta($post->ID, 'key', true); ?> (not “key” is hte same name set in the $key value at the very top of the array in the plugin/function). Now it’s a matter of simple calls to get the rest. Just want to grab what’s in the input and textarea fields?

Input field: <?php echo $fields['input']; ?>
Textarea field: <?php echo $fields['textarea']; ?>

note “input” and “textarea” within the brackets are the initial array names.

Works the same with the “Radio” field. Since radio buttons are a one-shot deal (you can choose one item only), it works in the same manner:

Radio field: <?php echo $fields['radio']; ?>

Dropdown is the same way as well – as long as only one option is chosen. If you allow multiple options to be selected, then you’ll want to deal with it the same way as you will your checkbox values. So, checkbox1 is a choice of 6 options. To obtain the checked values, we do a simple bit of code (using extra brackets, because it’s an array within an array) to do a foreach loop and yank out every single one of them:

Checkbox field: <?php if($fields['checkbox'] != '') {
foreach ($fields['checkbox'] as $value) echo $value . ' ';
} ?>

Checkbox 2 is a “yes/no” type option – so we can do a quick little test for that as well:

Checkbox 2 field: <?php if($fields['checkbox2'] != '')
echo 'yes'; // if the box is checked
else
echo 'no'; // if it's left unchecked
?>

And that’s all she wrote!

WordPress 3.0 – it’s official!

WordPress 3.0 “Thelonious” was officially released yesterday. Now, I posted before about the cool new features of WP 3.0. I’ve been using it since the Alpha, and I’ve been very impressed.

I’ve been getting a ot of questions in my inbox, as well as on Twitter, about how it’s going. A lot of people out there are pretty wary of immediately upgrading to a new version of WordPress, and typically wait until at least the first “patch” release before they’ll implement it.

Believe, me, as a user of WordPress since version 1.5, that’s my typical stance. I’ll wait until the first or second “security release” comes out before I dive into a new version. It’s actually a very smart move, and I don’t fault anyone for taking that safe stance – especially with clients.

However, this particular release was too mouthwatering for me to wait on. I have a pro-bono client that I’ve maintained for about three years now. It’s an extensive local nonprofit club in my area, that wants to “get into the new age” and go digital. In September, they will be beginning their new year, and they want to be completely paperless. They’ve had me code and test and manage their site during all of this time, and I’ve been constantly working on the site – as I learn new things that would streamline their site and it’s effectiveness, I apply it. However, there’s always been this one sticking point with me: their newsletter. Apparently, their newsletter isn’t a “normal” one, and I’ve had to hack and pray to get their newsletter to function the way it needs to. (Their list of requirements is seriously long, so I won’t go into it here.)

But then the clouds parted, and the angels wept when I saw WP 3.0 Alpha. Because of this particular client, I dove in. I NEEDED my sanity. I NEEDED this site to work as it should.

Granted, I’m not finished with it yet – when I say their list of requirements is long and convoluted, I mean it. THREE YEARS people. That’s how long I’ve been pulling at this thread, trying to get it to make sense and work right. And I have until the end of August to get it going good and proper. Because of this client, Iv’e actually gotten to dve in and get to know this new version, and I must say I adore it.

I’m positive there will be bugs and patches released – every WordPress version goes through this. But this time I actually got to participate in the process. I joined the WP Testers list and saw what these people do – and it’s amazing. There was one moment where I actually found a bug, and I briefly though about actually helping out and applying a patch for it – but I’m not secure enough in my skillz, so I didn’t. I reported, but I let someone else fix it – because I was sure that whatever fix I put in would break something else LOL but because I just sat back and listened to this list, I saw what was oging on, became familiar with things that really aren’t even in the Codex yet, and I got to toy with it like you wouldn’t believe. many of the plugins and functions I use work fine – but a few did not, and I had to fix them (I shall have to post what i did so others can benefit from this): two major ones (for me, anyway) were the Userextra/Usermeta plugins, and the function for Custom Write Panels, the tutorial as written by Liam McKay over at wefunction. LOVE Liam. He’s so smart – and very kind and helpful. But I feel all empowered and stuff because when I used his tutorial in 3.0, it broke – and I FIXED IT! (I also figured out how to add checkboxes, radio buttons, etc. for the fields too. There’s another post coming up I guess!)

Anyway, I just wanted to post about this because I know a lot of people out there are very wary. But I’m telling you, this one’s worth the risk. There’s so much goodness in this release that I just don’t know how you can wait. At the very least, you should download it and play on your own development server – it’s so worth it.

And yes, I know I haven’t upgraded this site yet. There’s a good reason for that – and it pretty much involves “new design so why bother?” LOL

Nice little Twitter Widget

So I was wanting to find a nice, simple method of using Twitter to pull in multiple accounts into a single feed. “Why would you want to do that,” you ask? Well, in my case, I was working on a site for a client who runs an organization. The organization itself has a Twitter feed for announcements and such, but its employees each had their own Twitter account as well. So they wanted to pull in the feed from their employees onto the site, all into one feed.

Now, I wasn’t sure if it was possible, because the javascript Twitter usually gives you only allows for one name to be used, and I’m no JS expert at all. So I armed myself with Google and searched.

I came up with three things: 2 were results and one was knowledge. The “knowledge” part was that yep – I’m not the only one who wants to do this, and that yep, it’s pretty hard to accomplish – but I also found that (as usual) I didn’t have this desire first, and there were a couple of methods to pull it off. The most interesting one I found was this one by Sea of Clouds.

The script on it’s own is totally usable, but because I have clients who are hard-pressed to understand what the “power” button is for on their computer (not ALL of them, but some!) I always try to make things as easy as possible for them. So I made a widget for the system, because otherwise, they’d have to read through a lot of javascript code to edit names and such – which is never a good thing to do. For this site, all I needed was the ability to add one user, or sixty users (“sixty” just being a number I randomly said – I basically needed as many as was desired), and the ability to easily add or remove them from the list. The script linked above allows for a LOT more capabilities than that – so if you see something that you wish to be added to this widget, the following code should give you an awesome head-start on it. (In fact, I’m considering turning it into a full-on WordPress plugin, it’s so awesome.)

So without further ado, here’s the code. Just copy and paste into your functions.php file, and it should show up as a reusable widget. This does not allow you to change the title of the widget, nor how many tweets are shown – but if you know enough about what’s going on here and what I’m about to post, you shouldn’t have any issues editing the below code to fit your needs.

First, you need to download the source. (scroll past the demo to the “Download” area.) Make sure you’re running jQuery 1.4.x, minimum. Upload the script files into your theme directory.

Next, you need to open up your header.php file and add in your calls to the script files you just added to your themes folder:

1
<script type="text/javascript" src="<?php bloginfo('template_directory'); ?>/scripts/jquery.tweet.js"></script>

Finally, you need to add the following code to your theme’s functions.php file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
add_action( 'widgets_init', 'twitter_feed_widgets' );

function twitter_feed_widgets() {
	register_widget( 'Twitter_Feed_Widget' );

class Twitter_Feed_Widget extends WP_Widget {

	function Twitter_Feed_Widget() {
		$widget_ops = array( 'classname' => 'twitter_feed_widget', 'description' => __('Widget to display multiple Twitter accounts (or a single one) into a single feed.', 'twitter_feed_widget') );
</code><code>
		$control_ops = array( 'width' => 300, 'height' => 350, 'id_base' => 'twitter-feed-widget' );

		$this->WP_Widget( 'twitter-feed-widget', __('Twitter Feed Widget', 'twitter_feed'), $widget_ops, $control_ops );
	}

	function widget( $args, $instance ) {
		global $post;
		extract( $args );
		$accountlist 	= $instance['accountlist'];
		$defaultacc	= $instance['defaultacc'];

		// first we will want to see if we are on a single post page, so we can just grab that user's feed only - userextra and usermeta plugins are required, and a profile field named "twitter" needs to be added

		if(is_single()) {
			$author = $post->post_author;
			$twittername = get_usermeta($author, 'twitter');
			// strip "@" if exists

			$find = strpos($twittername, '@');
			  if($find !== false) {
				$twittername = str_replace('@', '', $twittername);
			  }
			$followlink = 'http://twitter.com/' . $twittername;
			// now add script to pull feeds

			$script  = '<script type="text/javascript">' . "\n";
      		$script .= 'jQuery(document).ready(function(jQuery) {' . "\n";
      		$script .= 'jQuery(".twitter_feed_widget").tweet({' . "\n";
      		$script .= 'join_text: "auto",' . "\n";
      		$script .= 'username: "'.$twittername.'",' . "\n";
      		$script .= 'count: 3,' . "\n";
      		$script .= 'auto_join_text_default: "we said,",' . "\n";
      		$script .= 'auto_join_text_ed: "we",' . "\n";
      		$script .= 'auto_join_text_ing: "we were",' . "\n";
      		$script .= 'auto_join_text_reply: "we replied to",' . "\n";
      		$script .= 'auto_join_text_url: "we were checking out",' . "\n";
      		$script .= 'loading_text: "loading tweets..."' . "\n";
      		$script .= '});' . "\n";
      		$script .= '}).bind("empty", function() { jQuery(this).append("No matching tweets found"); });' . "\n";
      		$script .= '</script>'."\n\n";      		

		}  // if we are on any other page, we want to pull the feed that includes everyone

		else {
			$accountlist = str_replace(", ", ",", $accountlist); // remove whitespace and leave commas

			$accountlist = str_replace(',', '", "', $accountlist); // seems redundant, but do it again to add in spaces and apostrophes in the proper order

			$followlink = 'http://twitter.com/' . $defaultacc;
			// now add script to pull feeds

			$script  = '<script type="text/javascript">' . "\n";
      		$script .= 'jQuery(document).ready(function(jQuery) {' . "\n";
      		$script .= 'jQuery(".twitter_feed_widget").tweet({' . "\n";
      		$script .= 'count: 3,' . "\n";
      		$script .= 'username: ["' . $accountlist . '"],' . "\n";
      		$script .= 'loading_text: "searching twitter..."' . "\n";
      		$script .= '});' . "\n";
      		$script .= '}).bind("empty", function() { jQuery(this).append("No matching tweets found"); });' . "\n";
      		$script .= '</script>'."\n\n";
		}

		echo '<div class="widget twitter_feed_widget">' . "\n\t\t\t";

		echo $before_title . 'Twitter Feed &lt;a class="followlink" href="' . $followlink . '">> follow</a>' . $after_title; 

		echo $script;

		echo '<!--/close twitter feed widget-->' . "\n\t\t\t";
		echo '</div>' . "\n\n";
	}

	function update( $new_instance, $old_instance ) {
		$instance = $old_instance;
		$instance['accountlist'] = strip_tags($new_instance['accountlist']);
		$instance['defaultacc']  = strip_tags($new_instance['defaultacc']);
		return $instance;
	}

	function form( $instance ) {

		$defaults = array( 'accountlist'	=> __('', 'twitter_feed'),
					    'defaultacc'	=> __('', 'twitter_feed')
					);
		$instance = wp_parse_args( (array) $instance, $defaults ); ?>

		<p><small style="display:inline-block; color:#777; font-style:italic; padding-bottom:7px;">Enter in a comma-separated list of twitter account usernames that you wish to have added to the feed. Do not include the "@" symbols.</small>
		<label style="vertical-align:center;" for="<?php echo $this->get_field_id( 'accountlist' ); ?>"><?php _e('Account List:', 'hybrid'); ?><br />
		<textarea class="widefat" rows="5" cols="20" id="<?php echo $this->get_field_id( 'accountlist' ); ?>" name="<?php echo $this->get_field_name( 'accountlist' ); ?>"><?php echo $instance['accountlist']; ?></textarea></label>
		</p>

		<p><small style="display:inline-block; color:#777; font-style:italic; padding-bottom:7px;">Enter in the default account name (sans "@" symbol) to be used sitewide. If you are also using the "Feed and Follow Widget", you will probably want to use the same user account set for the "Twitter Username" in that widget. </small>
		<label style="vertical-align:center;" for="<?php echo $this->get_field_id( 'defaultacc' ); ?>"><?php _e('Default Username:', 'hybrid'); ?>
		   <input id="<?php echo $this->get_field_id( 'defaultacc' ); ?>" name="<?php echo $this->get_field_name( 'defaultacc' ); ?>" value="<?php echo $instance['defaultacc']; ?>" style="display:inline; border:1px solid #ccc; width:183px;" /></label>
		</p>

	<?php
	}
}
}

Now, you should see up there that I included a reference to “Userextra” and”Usermeta” plugins. I love these two plugins – I’ve used them for a long time to add custom fields to my profile pages and I just haven’t found anything that’s works better for me. The above code has a “main feed” icon in the header tag. It didn’t make sense to me that you would have a “follow” link in the header, but listing 2, 5 or 50 different people in the feed. Who are you following? So what I did was provide a “twitter” field in the user’s profile page, to which they would put in their Twitter username. If you’re on a single post, the widget will look up the name of the page’s author, pull the twitter account name, and link it to the “follow” link in the header. It will also only list the feeds for that particular other. But when you’re on any other page on the site, it will list the multiple accounts you’ve entered into the widget, and make the “follow” link go to the main/default Twitter account.

So there you have it – enjoy! (and if you all talk me into actually turning this into a full-blown widget, you won’t have to push very hard. I love this one!)

WordPress 3.0

Yes, I said it. And any of you who are WordPress fanatics probably already know about it. But I, being a lowly developer still on sabbatical, just heard about it this morning. I received an email from an old colleague of mine to inform me of this fun new release.

Rumor has it that WordPress 3.0 will be released on May 1, 2010 (just in time for my birthday!), and that it will include fun new features like combining WPMU with the regular WP installation (so you can have all the multi-blog fun of WPMU but using a regular single installation that’s not run by the MU – if that makes any sense!) We will also say bye-bye to Kubrick as the default theme, and hello to “Twenty Ten” to replace it.

As I said, these are rumors. But hearing just these juicy tidbits got me fairly excited. I haven’t really been this excited about WordPress in quite a while. I was so happy to hear this stuff this morning that I actually logged into the subversion access and downloaded the alpha, and installed it on my localhost – something I haven’t done in a very long time.

I’m going to tell you the cool stuff I’ve noticed right off the bat. Now keep in mind, this is just the alpha – which means the things I’m noticing could easily be changed. (This also makes me think that the May 1 release date is probably just for beta testing, because to actually have the release fully completed and issued as a release candidate by that date seems very ambitious to me.) But even so, just the installation process has such neat changes that I would be happy with just that! So do bearing mind that any of these things I’ve seen could be scratched at any point prior to beta testing for various reasons.

1. Better Installation Options
I can’t quite figure out the correct way to say this, so I went for the above line. it’s not that you have a crapton of new choices and options, but it seems to take security in mind. I’m not a “security guru” either, but I do know that when I install WordPress for anyone, I take certain steps to help aid in keeping it from being hacked. I do things like ensure the default “wp_” table prefix is changed in the wp-config.php file, and make sure I remove the default “admin” login and change it to something else.

WordPress 3.0 Alpha Installation Screen (as of March 7, 2010)3.0 takes care of at least part of this for you. Instead of assigning the default “admin” and random character password generated for you, you get to set it yourself during the installation process. As you can see (from the screenshot to the left) the regular same ol’ stuff is involved, but you can now create your own login name, and set your own password, without having to jump through the hoops of changing it after the installation process is complete.

I would also like to note that the old Authentication Keys (which you add to your wp-config.php file) have been expanded to include salts. Hackers will definitely have more work cut out for them if they want to break into your site. (Now, for each unique key, there’s a salt attached to it.) So I can definitely see how they are keeping security as a priority here.

2. Appearances
I can verify that the default theme (as mentioned above) is now “Twenty Ten“, but “Kubrick” and the old “Classic” are still standbys, and are still available to use.

Themes BrowserBut there is new awesomeness: the “Themes” section is now tabbed, so you can manage themes in one screen, and install new themes in another. Remember the old “themes.wordpress.org” site? Looks like we now have it in the back end of your WordPress area. You can browse through themes, select options for your search – very handy and totally cool. (it also appears you can do this with Plugins as well!) You can even upload your own custom theme work from the back end – no more need to FTP in and do your thing (just upload the .zip file and go!)

Total awesomeness – even though the “Widgets” area seems to be pretty much the same – you might notice a new option: menus. You can now create customized menus from the back end of your site – no more messing with tons of code to pull it off. Classes are even added to define your menu items (using “menu-item-Custom or “menu-item-page”, etc. and even further by assigning numerical items to each one for further CSS customization) to make it really easy to create a customized menu for yourself.

Even creating dropdowns is dead-easy – if you want a menu item to show up as the child of another one you’ve created, just drag-n-drop. Bam. it’s now a child, dropdown/flyout created.

Further coolness: you can create your own headers and upload your own backgrounds easily through the back end as well.

3. Exporting Content
Exporting now has new goodness: you can now define what you want to export. Before, all you had was an option to restrict your export to a particular author. Now you have the option to also restrict status, category, and what type of content (Pages? Posts? Or all?)

There’s still a lot of yummy stuff I haven’t completely trolled through yet – for instance I don’t see any indication that WPMU has been rolled into this as rumored. However, it does appear that you can download and install the BuddyPress plugin (which used to be solely for WPMU) and use it on single installations of WordPress. But this isn’t something that’s being saved for 3.0 – you can do it right now and use it with 2.9.x.

I stand freaking corrected! To enable “multiple blogs” on this, you just have to add the following line to your wp-config.php file:

define('WP_ENABLE_MULTISITE', true);

I’ll note here that – as with WPMU – it will not run on localhost properly just by using “http://localhost” or “http:/127.0.0.1″ – you have to have a virtual hosts setup. I have a tutorial on how to set up a local virtual host already, if you’re interested.Once you do that, and go under “Tools”, you will see a new menu item called “Network”. Hot damn, that’s cool. I picked up this tidbit on the wp-testers list, and from the discussion going on, this looks like a temporary thing. What I’m gathering is, at one time, there was just a button on the back end to enable this, but for some reason, it was removed in last night’s build, and this is the temporary solution while they continue testing.

All in all, this looks very promising to me. The new features that are put in here, I think, will not only aid the run-of-the-mill blogger to manage and control his own site, but I think that these initial things I see will also help developers who used to think that WordPress was too hard to code for become my competition :)

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
}
}

Newsletters and authors and printing, oh my!

So, I currently (and temporarily) handle a website for a not-for-profit club in my area. I took over almost 2 years ago when I volunteered to help the current webmaster when she was out on a vacation. At that time, the site was pretty much done through this process:

  • The person writing the article for the newsletter would submit a word document or HTML email to the newsletter editor, who would compile all of the information into one long Microsoft Word document.
  • The Newsletter editor would then send that .doc file to the webmaster, who would pick through the entire newsletter to link things that needed to be linked, change copy (as needed) to fit the web and do other assorted things to the file to make it internet-ready.
  • Such items would be to save all of the images in respective monthly folders
  • The webmaster would also create the HTML file from within Word and upload everything to the server – resulting in seriously bloated code, as well as cross-browser inconsistencies.
  • Doing all of this work also took a lot more time than was necessary, and archiving was completely manual.

So I decided to 1) give the site a new look, and 2) put it into WordPress so it was easy to manage everything. The new look wasn’t a problem…. but the newsletter was.

I’ve tried several “newsletter” plugins, some seemed promising, others were absolutely not – and none did exactly what I needed. So I began cobbling ideas and functions (and plugins) together to see if I could make something work. What I came up with worked rather well, but I’ve been using the system for almost 2 years now (and my term on the board as the newsletter editor is coming to an end – I have to hand this off to others who aren’t as “savvy” as I am) and in that time, I’ve seen the downside to what I’ve done, and how what was in my head doesn’t translate well to real life.

So now I need to revamp the back-end of this site to pull off my needs. There’s only a few places, really, that need redone – but they are biggies. I’m working to figure out the best way to do it. Here’s a few of the issues I have, and thoughts on how I can fix them. Keep in mind, these are thoughts only – not definites. I’m sort of thinking out loud here. In the end, I can see me writing some type of plugin, and it’s possible I would release it to the public, if it proves to be what others might be looking for.

The Current State of Things, from the Club Perspective
Basically, the club wanted a simple, informational site. Something that allowed people to easily get information on what the club is, how to join – that kind of thing. They also wanted some “fun stuff” – photos and events, news releases, etc – to be filler. But the meat of the site is a) getting people to join and b) the monthly newsletter.

They also have someone who handles the membership aspect of the club – she has an excel file that contains all the information for each member that she updates monthly. Club members get a “directory” once per year that lists everyone who belongs to it, and chairpeople use the list often to print out labels for mailings (like invitations to club events, etc.) However, using an excel file (especially when they like to export it as a Word document) makes it really hard to format this stuff, and too much time and effort, IMO, is put into something that could be made relatively simple.

What I have done
I converted the site to a CMS (WordPress) System. However, I began running into issues. The first one was the fact that the newsletter was due to be released on the 20th of the previous month. For example: the December newsletter would come out on November 20th. My only solution (thus far) as been to use the WordPress tagging system, and tag the articles by the month it was to be released, not the month it was published, so that the archives would correctly reflect the date of the article. The issue with this: the WordPress tagging system has no method of ordering by date – so right now the listing for the newsletters are in alphabetical order – not in order by month and year.

The tagging system also worked well, because there are several articles that chairpersons put out that are recurring – they say the same thing (or almost the same thing) every month – so really they are monthly reminders that a particular sub group or event is always out there., and if you’re interested in joining, it would tell you who to contact. So rather than having to repost the same information as a new post month after month, I can simply tag the article for the month and year of the newsletter it’s supposed to be in, saving me from having to rewrite it over and over again. The issue with this: is I have to manually tag each post over and over again. Some of the posts are getting REALLY long in the “tag” department. It would be so much nicer if there were some method to automate it. Like write a post once, and then schedule it to post on the 20th of every month, and then no one has to think about it again until the next year.

Another thing was the articles themselves. I have a rather convoluted system in place for setting who the authors are, and what order the articles display in. Now WordPress has a system in place so you can easily set another registered user as the author of a particular article. My original idea was that it would be supremely easy if I set all board members and activities chair members with their own login to the site, and they could write their own articles. That way, people had control of their content, all the editor had to do was go in and edit the articles and make sure the correct information was there, and publish everything. Life would be easier for everyone. Another plus was that if someone need to email the board, or their particular subgroup, all they had to do was login, check a box, write the email and send it. However, much to my chagrin, I’ve since discovered that no one is interested in this. (as a side note, it’s a little frustrating – since the point of doing all of this was to make their lives easier. They were all excited about this setup, but when I finally finished it and wanted to get a session together to show people how to do it – not a single person was interested.) They like the idea, but no one wanted to learn how to do it (even as simple as I made it) – I guess it falls under “old dog, new tricks” or something. So now I have a bunch of authors, but only one person actually doing anything – me.

The articles themselves have the same title every time. However, the interesting thing is, every 2 years, the board positions change. So I had to figure out a method to have the articles attributed to a position, not a particular person. I also needed the old information to stay the same – so if I updated a person’s position, the old articles (from when a different person held that position) would still have the correct info for that year. It also had to pull in the correct email address and phone number for that person.

The articles also had to appear in a certain order: the board positions in a particular order (that really couldn’t be set by a simple “ASC” or “ID” call), and then the sub-groups were listed in alphabetical order.

The issue with all of this: when I write a new post, I have to manually look up who currently holds the position, and their contact information, and add it every time.

If I could have a wishlist on how to fix the back end of this site, it would be as follows:

  • Somehow make WordPress see the posts, and if it’s published between the 1st and 15th of the month, it archives it in the following month. (i.e. if an article is published November 13th, 2009, it would immediately date-base-archive itself into December 2009.) Then I would no longer have to tag everything every month, nor would I have to try to come up with some system to force the tags to display properly.
  • Have some sort of system in place where the recurring articles would have a “default” post that shows every month, but for those rare occasions when they need to alter a word or two, they wouldn’t need to rewrite the entire thing for such a small change, and these recurring posts would re-publish themselves on the same day every month. Sort of like a simplified version of the “post revisions” you see in the back end. That would be cool.
  • Somehow have the system look at the post title or category, and pull from another file or database entry as to who currently holds that position and their contact information and shove it into a custom field. That way, past entries have the correct information for them, while current has the correct info, and all you’d need to do is change the info in the “placeholder” file (or plugin).

Currently, I’ve also got the Tribulant.com’s Mailing List Manager plugin going. I really like it, but I would like it a lot better if I could streamline the management. Right now, I have to search for users when I need to do something – and it would be a lot “awesomer” if it behaved a little differently. There’s a lot to that, though, so it’s hard to describe what I mean.

I’d also like a nicer system for printing the newsletters. Right now, once everything is on the website, I have a print stylesheet set up to display everything properly to print (and mail out hard copies to members), but you have to know some CSS to make it lay out properly every month. An easier system would be terrific. Perhaps something as far as asking on individual posts what margin you’d like to set it at, and where the line breaks should be – that way messin’ with CSS wouldn’t be necessary.

And finally, I’d love it if the chairs and board members would be willing to learn to use the system so they can actually enjoy the benefits of what’s going on here. However, that’s not a coding issue – it’s a people one.

So that’s where I’m at with this. My term as “editor” ends in July 2009, and I have to hand the reins over to whoever gets the position after me. I also have to give the “webmaster” status back to the actual webmaster (who probably hates me now because she hasn’t done anything for almost 2 years – she probably thinks I stole it away from her!) I’d love to be able to hand it back over with everything in place, dead-simple and easy to use, and easy to maintain.

So please feel free to discuss – because I’d love some other great minds on this one! Obviously me banging my head isn’t coming up with a ton of terrific ideas all on it’s own! I’d love some input from others. Any ideas are welcome.

Beginning my adventure with ModX

So, many people know that I do a lot of WordPress work, and have been doing it for a long time now. I believe my first foray into the WordPress world was sometime when version 1.5 was the newest release – so it’s been a while :) It’s been a wonderful ride, too.

No, I’m not getting off…. but I am test driving new cars.

One of the things I promised myself I would do while I was on this sabbatical was finally delve into things I’ve been wanting to learn, but never had the time to do. One such thing is a CMS platform called ModX. An old design colleague of mine first introduced me to this CMS, and has touted it’s wonderful-ness (about as much as I’ve touted WordPress to her), and she has since made the dive in trying WordPress out for herself. She’s done so many wonderful, wonderful things with ModX that I’ve been itching to take her advice and try it myself.

So this morning, I began my foray into the world of ModX. I downloaded the latest release and installed it on my loacalhost environment. So far, this is as far as I’ve gotten – but I wanted to stop and share these first steps with you.

WordPress has a “Famous 5-Minute Install,” and I have to say, ModX was just as easy to install…. quite possibly even easier, at least from a layman’s standpoint. (From my perspective as a programmer, it was on the same level, really.) I could see a lot of people who’d want to try out ModX thinking that it’s a lot easier to install than WordPress, because the installation process handles everything for you. Basically, it asks you a few questions (such as your database name and password) and then asks you if you want to use an existing database name, or have ModX create one for you (and if it creates it for you, you can choose what you want it to be named, as well as use the default table prefixes or one of your own making.) It’s really just a series of questions, and you can test each of your answers to see how it’s going through the process. If there’s a bump, it lets you know, and even suggests how to fix it.

At the end, you hit “install” and it lets you know, line-by-line, if the installation is going okay. It was really pretty freaking awesome.

And that’s all I had to do. It was literally less than 5 minutes to install it.

Right now, I’m perusing through the back end (from what I can see, it’s cool), and I’m looking on the ModX site for the documentation (when I work in WordPress, the Codex is my best friend, with the forums coming in a close second.) So far, I’ve found some promising things: they do, indeed, have a support forum, a wiki (the equivalent of the WP Codex, from what I can see), and a page that links to these items as well as an IRC channel! (Holy cow! I haven’t used IRC in freaking FOREVER.)

I think this is gonna be fun. :)

Client instructions through the WordPress admin

So I currently have a client that – no offense to anyone, I swear it – cannot seem to handle instructions to save his life. I’ve written two PDF documents, as well as one in Word format, as well as multiple phone conversations, and having an “Active Collab” type area where your discussions are stored for future reference – and finally emails. However, I still find myself repeatedly giving him instructions, because if it’s not right in front of his face, he forgets (or doesn’t bother to go looking). It is a lesson in frustration, because I’m starting to sound like a broken record to myself.
read more »