Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: wordpress

  • WordPress MultiSite – New Dashboards

    WordPress MultiSite – New Dashboards

    Back in the WordPress MU and the recent WordPress Multisite 3.0.x days, we had something called a ‘Dashboard Blog.’ This was the ‘main’ site of your install, and ostensibly was the default blog to sign users up to and control them from. This was also where you, the admin, had the Super Admin menu. So what were those things for and why were they moved? After all, a lot of people will tell you they worked just fine.

    The simplest answer is that it’s considered good design to separate the ‘user’ interface from the ‘admin’ interface. That’s why, when a regular user with the lowest role possible logs in to a regular (non-MultiSite) WordPress install, they see a very limited site. They see a dashboard, their profile, and that’s it. You want to keep the subscribers out of your meat and potatoes. Pursuant to that, there are plugins like WP Hide Dashboard that kick users to just their profile. I love that plugin, because it hides the man behind the curtain. If the Dashboard of WordPress is not a part of your desired experience (and really, it only is for the people who run the site), then you keep Dorothy, Toto, the Scarecrow, the Tin Man and the Cowardly Lion out, Ruby Slippers or not.

    When WordPress 3.0 came out, it was a bit of a chimera. We’ve got all sorts of weird parts where we call things blogs instead of sites, and from the back end, it’s really confusing. The sad thing is we cannot declare fiat, fix it all, and move on, because that would break backwards compatibility. Did you know WordPress is backwards compatible, nearly all the way to the start of WordPress 1? (17 Reasons WordPress is a Better CMS than Drupal – Mike Schinkel, Dec 1st, 2010) In order to be able to upgrade from WordPress MU (which was a fork – i.e. a totally separate version – of WordPress), the fold-in of MU to regular WordPress was a lot of work and duplication. There are some things I’m sure the devs would have chosen to do differently in a perfect world, but they decided the headache for them was worth it because it was beneficial to the users. For that alone, I laud them and owe them beers and coffee.

    One of the many drawbacks of that mentality is the users are very much used to getting what they ‘want.’ The users think ‘This worked before, it will always work, therefore, it’s cool to do it now.’ Take (not for random example) the issue with the /blog/ folder in the main site of any subfolder install. (Switching to WordPress MultiSite Breaks Links – Mika Epstein, 14 July, 2010) Back in the 3.0 days, we had a work-around to fix this, but that was a ‘bug.’ We were all taking advantage of a flaw in the system, and that flaw was plugged (mostly) in 3.1. Of course, fixing the flaw meant breaking things, and those people who were not up to speed on the dev channels (which in this instance included me) went ‘Hey, what the hell!?’ We were angry, we were upset, and then Ron told me that it was bug and I stepped down.

    A lot of people are still annoyed by this, and while there is still a buggy workaround, it’s not something I would generally suggest be used for my clients (myself, yes). Then again, the original tweak wasn’t something I considered using for clients, since I was always aware that WordPress’s stated intent was to make that /blog/ slug customizable. And I hope they do.

    What does this have to do with the new dashboards? It’s another change WordPress implemented to ‘fix’ things people didn’t see as broken. The people are wrong.

    Now don’t get all het up, thinking I’m drinking the WordPress Kool-Aid. There’s a vast difference between being ‘WordPress is always right, WordPress can do no wrong’ and the acceptance that what WordPress did was for a good, understandable, reason. In software development, I’ve learned to distance myself from the all too personal feelings of investment in my product. Many times, the product needs to be designed in a certain way to work better for the majority of people, and many times, I am not that person. Look at JetPack. This is a fantastic plugin for people moving off WordPress.com and onto self-hosted WordPress. It has absolutely no meaning to me, and I won’t be using it. But it’s great for the target audience. I accept that I am not that audience, and I look at the product with as unbiased an eye as is possible.

    I have to look at the Network Admin and User Dashboard the same way.

    The Network Admin was moved from a Super-Admin sidebar menu to it’s own section, in order to provide a clearer delineation between Site Admin (in charge of one site) and the Network Admin (in charge of all sites). (Network Admin – Trac Ticket) (Network Admin – WordPress MustUse Tutorials, October 21, 2010) This is a basic, normal, every-day bit of separation in my everyday life. For one app I use, I even have a totally separate ‘Admin App’ to use when I want to control the whole network, versus just one part of it. It’s done for security, but also to kick our brains over and go ‘Hey, moron, you’re in the Network admin section!’ Our brains need that kick, and it lessens the human errors. In doing this, we also found the plugin management was separate. Per-site admins saw the non network-activated plugins only. The Network Admin had to go to the Network Admin section to see the network-activated plugins and the must-use plugins, though many plugins needed to be recoded to handle this move. (Adding a menu to the new network admin – WordPress Must Use Tutorials, November 30, 2010) While this is annoying and takes a little time to get used to, this is good, sound UI/UX. It’s called “Separate of Duties” in the buzzwords game, and it’s really a blessing.

    Once they moved the Network Admin, the devs took a shot at getting rid of the Dashboard Blog. (Personal Dashboard – trac ticket) Once you moved the super users off to their own network, there’s no need to sign-up users to a main blog. I assume this was originally done becuase you had to hook them in somewhere with 3.0, to make them be a ‘user.’ Well, now WordPress.org Multisite now behaves like WordPress.com. You sign up for a blog but unless you get assigned a role to the blog, you’re not a ‘member’ of the blog. And you know… that’s sensible. You have no real role as a psudeo-subscriber. Nor do you need on.

    As I pointed out, part of the goal with moving the menus to Network Admin is that the whole ‘Dashboard Blog’ concept was a massive annoyance to everyone code-wise and UI wise. Having to say “Oh yeah, the main site is the master site and it’s where I control the universe” is logistically unsound. Much like you cannot in-line edit posts, you should not be mixing up Admin and User areas. So to further that separation, your users are not assigned to any site when they register. I find I need to repeat, a lot, that in most cases, this has no effect on usability. It doesn’t affect my BuddyPress site at all, because the users are the users. They just don’t have blog access. They can comment, which is all they need to do for me, and they’re happy. If they need to make posts, I can add them if I want to. But now I have security, knowing they can’t accidentally get in and poke around.

    Like it or not, it’s not going away. And most of us won’t need it to come back. I do know that some people do need it, and are struggling to find a way to auto-assign users a role on their main site at ID creation, so if you know of a fix for 3.1, please share it!

  • WordPress 3.1 and Network Menu

    WordPress 3.1 and Network Menu

    This one’s really fast, but the word should get out there. It’s extremely important if you’ve built a BuddyPress plugin, because the BuddyPress menu has been moved. If you do not do this, your BuddyPress menus will vanish, and you will have very angry users.

    WordPress 3.1 has moved the admin menu for MultiSite. Instead of having a Super Admin menu available on the sidebar of your Admin section all the time, there’s a new link in the header bar for Network Admin. Thats right, it’s its own page! The problem with this is that a lot of plugins aren’t ready for that and because of the move, their admin menu links vanished.

    Thankfully it’s an easy fix!

    The WP Codex Doc on Admin Menus tells us to use “admin_menu” when adding menus. Well, if you want your plugin to show up on the Network Admin page, you have to use “network_admin_menu” instead. (Trac #14435)

    See? I said it was easy.

    add_action( 'network_admin_menu', 'MENU_FUNCTION', ## );
    

    There’s on catch to this. What if your plugin is for Multisite and NON MultiSite? Honestly I don’t know if this matters, but just to be safe, I would do this:

    if ( is_multisite() ) { 
         add_action( 'network_admin_menu', 'MENU_FUNCTION', ## );
    } else {
         add_action( 'admin_menu', 'MENU_FUNCTION', ## );
    }
    

    Or this:

         add_action( 'network_admin_menu', 'MENU_FUNCTION', ## );
         add_action( 'admin_menu', 'MENU_FUNCTION', ## );
    

    That’s right! If it’s there and not-needed, it does no harm! I’m not 100% certain right now if you need to do this for the non-menu calls people make (like calling a function on admin_menu to check for installation), but I’ve been adding it in to no ill effects. I figure, the BuddyPress core code does it, so it can’t hurt!

  • WordPress Google Libraries

    WordPress Google Libraries

    A lot of people would rather use Google Hosted JavaScript Libraries. Why? Here are three good reasons. Okay, great. How do you do it in WordPress? DigWP has you covered.

    But if you want to do it for WordPress MultiSite, for all sites on your network, you can toss this into your mu-plugins folder. I named my file googlelib.php and dropped it in. Bam.

    Oh and there’s also the Use Google Libraries plugin, by Jason Penney, which works great too. Just drop the use-google-libraries.php file into your mu-plugins folder and call it a day.

    <?php
    /*
    Plugin Name: Google Lib
    Plugin URI: http://digwp.com/2009/06/use-google-hosted-javascript-libraries-still-the-right-way/
    Description: Use Google Hosted JavaScript Libraries (... Still the right way)
    Version: 1.0
    Author: Mika Epstein
    Author URI: http://ipstenu.org/
    */
    
    if( !is_admin()){
       wp_deregister_script('jquery');
       wp_register_script('jquery', ("http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"), false, '1.4.4');
       wp_enqueue_script('jquery');
    }
    
    ?>
    
  • Customizing a Sidebar Profile – BuddyPress

    Customizing a Sidebar Profile – BuddyPress

    I was looking at BP Tricks and thought ‘You know what would rock my site? A sidebar profile controller!’ Turns out this is pretty easy and only ‘requires’ two plugins.

    My final product (see left) isn’t super impressive, but it’s pretty simple and easy to use. The basic idea is that I have two master widgets. One is what the non-logged in user sees (a simple signup window) and one is what the logged in user sees. The logged in user should be able to see their profile info, their notifications and anythign else I want. Before I got started I made a list of what I wanted them to see.

    • Profile – This lists your profile, edit links, settings links, and a logout link
    • Notifications – This lists everything that can email you: notices/messages, comment subscriptions, newsletters, mailing lists
    • Achivements – I use Paul Gibbs’ Achievements for BuddyPress
    • Activity – Links to the various activity screens

    First I decided I wanted an accordian style profile, where you had sections. I grabbed Tabbed Widgets and tossed that in my widget area. Then I used Widget Logic and set the tab to only show if a user was logged in. If the user is NOT logged in, I used the PHP Code Widget to display a login form. Since I’m using BuddyPress, I just grabbed this wholesale from the source.

    <form id="sidebar-login-form" class="standard-form" action="<?php echo site_url( 'wp-login.php', 'login_post' ) ?>" method="post" name="login-form"><label><!--?php _e( 'Username', 'buddypress' ) ?--> <input id="sidebar-user-login" class="input" type="text" name="log" value="<?php echo esc_attr(stripslashes($user_login)); ?>" /></label><label><!--?php _e( 'Password', 'buddypress' ) ?--> <input id="sidebar-user-pass" class="input" type="password" name="pwd" value="" /></label>
    <p class="forgetmenot"><label> <input id="sidebar-rememberme" type="checkbox" name="rememberme" value="forever" /> <!--?php _e( 'Remember Me', 'buddypress' ) ?--></label></p>
    
    <center><!--?php do_action( 'bp_sidebar_login_form' ) ?--> <input id="sidebar-wp-submit" tabindex="100" type="submit" name="wp-submit" value="<?php _e('Log In'); ?>" /> <input type="hidden" name="testcookie" value="1" /></center></form>
    

    I could have probably done this with a widget, but I like being able to customize my PHP as I want to. Next it was time to build my tabs. The Tabbed Widget plugin is pretty easy to use. You make your widgets in the Invisible Widget area and they show up available for the Tabbed Widget. Using the list I made above, I pulled in the obvious widgets. Three are PHP and one is the Achievements widget which came with the plugin. I dislike using plugins just for widgets, so my PHP is how I customized things. The PHP for notifications has extra cruft you probably won’t need, but I wanted you to see how you could easily port in any link.

    My profile

    <div>
    <div style="float: left; padding-left: 5px;"><strong>Hello, <!--?php echo bp_loggedin_user_fullname() ?--></strong>
     • <a href="<?php echo bp_loggedin_user_domain() ?>profile/">Visit My Profile</a>
     • <a href="<?php echo bp_loggedin_user_domain() ?>profile/edit/">Edit My Profile</a> 
     • <a href="<?php echo bp_loggedin_user_domain() ?>settings/">Edit My Settings</a> </div>
    </div>
    

    My Notifications

    • <a href="http://jorjafox.net/comment-subscriptions/">Edit Comment Subscriptions</a>
    • <a href="http://jorjafox.net/wp-admin/users.php?page=s2_users">Edit Daily Update Emails</a>
    • <a href="http://jorjafox.net/csiwatch/">Edit CSI Watch Subscription</a>
    • <?php if ( messages_get_unread_count() > 0 ) {
    	?><a href="<?php echo bp_loggedin_user_domain() ? rel="nofollow"><?php echo BP_MESSAGES_SLUG ?>">Inbox (<?php echo messages_get_unread_count(); ?>)</a><?php 
    } else {
    	?><a href="<?php echo bp_loggedin_user_domain() ? rel="nofollow">/messages/">No new messages</a><?php 
    } ?>
    

    Activity

    <div style="padding-left: 5px;">
    <ul id="user-menu">
    	<li><a href="<?php echo bp_loggedin_user_domain() ?>activity/">Site Activity</a></li>
    	<li><a href="<?php echo bp_loggedin_user_domain() ?>activity/just-me/">My Activity</a></li>
    	<li><a href="<?php echo bp_loggedin_user_domain() ?>activity/favorites/">My Favorites</a></li>
    	<li><a href="<?php echo bp_loggedin_user_domain() ?>activity/groups/">My Groups</a></li>
    	<li><a href="<?php echo bp_loggedin_user_domain() ?>activity/mentions/">@<!--?php echo bp_loggedin_user_fullname() ?--></a></li>
    </ul>
    </div>
    

    Once I was done making those, I just pulled them into my Tabbed Widget in the order I wanted, with the style and defaults I wanted. The rest was all CSS, which you can do yourself.

    Basically, this just goes to show you that you can do pretty much anything you want with WordPress plugins. I really only needed two to do this, though the third (PHP Code Widget) really helped me take it to the next level. If you’re PHP shy, you can use Login with Ajax instead of my ‘Login’ code, BP Notification Widget instead of my Notification code, and I’m sure people can pick out some alternatives to other code bits.

    Hope this gets you started!

  • How the WordPress Upgrade Works

    Edited: This post was linked to by the folks at WTC, so I’m getting a lot more traffic! If you asked a question, I will try to answer it promptly, but if you need serious help fixing a problem, please consider posting in the WordPress forums for help.

    I was 90% sure about this before I started writing the post, and Andrew Nacin was nice enough to tweet me the exact file I needed to look at, so when I got home to look, I was ready to go!

    There are two kinds of automated upgrades for WordPress. The main ‘core’ upgrader and then the ‘child’ upgrades used for themes and plugins. They behave differently.

    Most of the time, we all see the plugin and theme installer, where it downloads the plugin to /wp-content/upgrade/, extracts the plugin, deletes the old one, and copies up the new one. Since this is used more often than the core updater (most of the time), it’s the sort of upgrade we’re all used to and familiar with. And we think ‘WordPress deletes before upgrading, sure.’ This makes sense. After all, you want to make sure to clean out the old files, especially the ones that aren’t used anymore.

    This is not how a core update works.

    WordPress core updates, the ones to take you from 3.0.3 to 3.0.4, do not run a blanket delete. They don’t even run a variable delete. They don’t even run a wild-card delete on files in wp-admin (which they could). Instead they have a manually created list of files to delete, files that have been deprecated, and delete only those files. Here’s a snippet of what it deletes:

    $_old_files = array(
    'wp-admin/bookmarklet.php',
    'wp-admin/css/upload.css',
    [...]
    // MU
    'wp-admin/wpmu-admin.php',
    'wp-admin/wpmu-blogs.php',
    [...]
    
    // 3.1
    'wp-includes/js/tinymce/blank.htm',
    'wp-includes/js/tinymce/plugins/safari',
    [...]
    'wp-admin/images/visit-site-button-grad.gif'
    );
    

    As you can see, the files and folders are all very carefully specified. They are not ac-hoc, they are all determined based on what WordPress has removed. If you read the whole thing, the part that would impress you the most is, perhaps, the folder wp-content, where your themes and plugins are installed, is nowhere on that list. Don’t believe me? Go look at wp-admin/includes/update-core.php and search for it. It’s not not there!

    Once the old files are listed, remember that we have not deleted anything, the upgrader runs through 9 steps.

    1. Download the zip file of the new release, unzip it and delete the zip
    2. Make sure the file unzipped!
    3. Make a .maintenance file in WordPress base (this makes your blog ‘down for maintenance’ so no one can do anything and screw you up mid-stream
    4. Copy over the new files. This is a straight copy/replace. Not delete.
    5. Upgrade the database. This may or may not happen.
    6. Delete the unzipped file
    7. Delete the .maintenance file
    8. Remove the OLD files. This is where it goes through the list of deprecated and unused files and deletes them.
    9. Turn off the flag that tells you to upgrade every time you’re in wp-admin

    Nowhere in there is wp-content and your themes mentioned.

    Well, except in this one weird way.

    See, in order for WordPress to work out of the box, a theme must be included, right? WordPress has the default theme of Twenty Ten. Now, I’ve mentioned before that you should never update your themes directly, and instead make child themes. This is why. When the WordPress core files update the copy over everything. Included in everything are two plugins (Akismet, Hello Dolly) and one theme (Twenty Ten).

    Normally this isn’t a problem. Sure, someone always edits those files directly and lives to regret it, but they do live. This last cycle, with 3.0.4, Akismet was accidentally rolled back from 2.5.1 to 2.4. Again, normally? Not a problem. We just upgrade our Akismet installs, remark on the silliness and annoyance, and move on. The problem for one user is she had another plugin or theme edit that hooked into the new Akismet. With the way WordPress updates core, it only deletes the files it knows to delete (and Akismet isn’t any of them) and it copies over the ‘new’ files. Or in this case, the old ones. Which broke her site. Her fix? Just re-update Akismet manually. Not a big deal and an easy fix. (Personally I think NOT updating core, even a security upgrade, with the latest Akismet is a poor choice, but the rational is that they want to keep it small and easy to maintain. So okay, I get why, I just don’t like it. I will support that as their choice, and continue to do my manual upgrades, which include deleting Akismet, Hello Dolly and Twenty Ten before I upgrade.)

    So then, why doesn’t this work 100% of the time? (Yes, I mentioned this before in the 3.0.1 days, but apparently it bears repeating. Read Why doesn’t the WordPress Auto-Upgrade Work? for more thoughts on the subject.) Well, to start with, that’s impossible. Nothing works 100% of the time. Me submitting this post won’t work 100% of the time. You safely walking up the stairs won’t work 100% of the time. This is just how the world works. There are, simply, far too many variables out there to allow this. Even though I make part of my living ensuring that I have an automated process run in a repeatable fashion, I tell people that I only ask for a 75-80% success ratio on the process before I’ll agree to automate it. Why? Because that’s actually phenomenal.

    If you take into consideration all the moving parts, variables, and possibilities that goes into any one individual WordPress install, it’s sort of impressive this stuff works at all. In baseball, if you hit a ball and get on base 33% of the time, you’re considered a fantastic hitter. If you do it 40% of the time, you’re pretty much promised a slot in Cooperstown. Whenever I try and sort out if something is worth the risk, I quote my father “What can go wrong? How likely is it? What are the consequences?” It boils down to an understanding of risk analysis, and what that actually means. The problem is that most of the people using WordPress are users. They’re not generally expected to think about risk. Not that many don’t, but just that Joe Blogger doesn’t tend to look at an upgrade as a ‘risk.’ After all, WordPress tested this, so it should be easy.

    Most of the time, it is. And when it’s not, it was an acceptable risk. All those horrible and terrifying outcomes you read about (from a very vocal minority) are gut-wrenching when they happen to you, don’t get me wrong, but at the end of the day, you have to ask ‘If I use the default WordPress theme and no plugins, do they happen?’ If the answer is no, then WordPress has done all the testing that is required. The onus is not on WordPress to test every upgrade with every theme and plugin. That responsibility is firmly on the shoulders of the person using the themes and plugins. A good developer tests their plugins and themes the moment a release candidate comes out for a new version of WordPress, and sorts out how best to support both the current users and the future ones.

    It’s what we call ‘acceptable’ risks. You take them all the time. You took an acceptable risk brushing your teeth. You take one every time you walk out your door. You know the risks and you accept them. So when you get to arguing that ‘WordPress upgrades always break’ or ‘I hate upgrading because it means my themes/plugins won’t work’ and using these as reasons to show that WordPress is bad software, then I think you’re missing the point. The more you customize, the more things break. This is something I mentioned in When To Code, and it bears repeating. The more you customize, the more things will break when you upgrade.

    But this is an acceptable risk for most of us!

    So when the WordPress auto-upgrade breaks, and I promise you, it will for you at least once in your experience, you have to learn to accept this. It’s not going to work on every server, it’s not going to work on every host. Your server is being constantly upgraded and tweaked. Security patches for PHP, FTP and everything else are applied, most of the time automatically so you don’t have to waste time thinking about it. And when you combine all those things, yeah, it’s going to break.

    This isn’t meant to scare you off of upgrading, but an attempt to raise your awareness of what’s going on, so when things break (and they will), you have a better understanding of why, and what to do. If the automated upgrade of WordPress breaks, upgrade manually. If every single automated install (upgrades, plugins, themes) always breaks, then start to diagnose your server. But if it’s a one off, just do it manually. It is, literally, copying files up to your server. If that’s too hard for you, you may not want to run your own, self-managed, WordPress install.

    As a blanket reminder, in order to prepare yourself for an upgrade, always make backups of your database and your files. A good backup. Never edit core files (even themes) and always remember that the computer is out to get you.

  • My WordPress Scripts

    My WordPress Scripts

    I actually have a couple little scripts I use to update my site instead of using the WordPress built in tools. Invariably, when someone has problems with the automated upgrade tool I comment that I rarely use it. That means people ask me ‘Well how do you update WordPress?’ and I tell them ‘Manually.’ Which isn’t really true. Sometimes I say ‘I wrote a script.’ So … here’s my scripts for upgrading WordPress. I don’t have one for themes, since I always do that manually and check everything. That’s the bane of having highly customized child themes.

    These are both Bash shell scripts and run perfectly happily on my server (Linux running CentOS). They’re GPL2, free, and somewhat use at your own peril.

    WordPress Upgrade Script

    WordPress Plugin Script

    As I went to post these, I took a bit of time cleaning them up, putting in comments (the ‘Blame Nacin’ bit is a joke) and formatting them nicely. When I started to look at the plugin one, I realized how freakin’ crazy it is and how many weird custom things I tucked in there. Also I made it so you always had to put in a version number, which if I wanted to ‘release’ that, is something to do away with. One of the catches with it is that a plugin’s ‘default’ zip file of plugin-name.zip is the trunk build. So you’d always have to know your version to upgrade.

    On the WordPress upgrader, I could trick that with a simple “if the version is ‘latest’, then download latest.zip”, because the WordPress most recent release is latest.zip. Now, I never call that. I like being master of my domain (pun? maybe) so I always make the time to know what I’m calling. I could have assumed that if you don’t put a version in, you want to install the latest, which is pretty easy to flip around, but I don’t like to assume like that. Still, you can take the code if you want it and do that.

    On the other hand, I think if someone wants a plugin, then they should be able to go ‘Get me the plugin’ and it should default to the latest. Probably this is because I test trunk WordPress a lot, but rarely do I trunk a plugin. Since there’s no easy to gank default like that for plugins, I came up with this really fun bit of code, shoved in an if-then check. I really like awk, by the way. It’s insanely powerful.

      # We're getting the readme from the repo and using that to calculate the latest stable release.
      wget -qO $1-readme.txt http://plugins.svn.wordpress.org/$1/trunk/readme.txt
    
      if ! [ -f $1-readme.txt ]
      then
        echo "FAILURE: The plugin is goobered in the WordPress repository, so we can't determine the latest stable release."
        exit 1
      else
        tr -cd '\11\12\40-\176' < $1-readme.txt > $1-readme-tr.txt
        VERSION=.`awk '/Stable/ {print $3}' $1-readme-tr.txt`
        rm $1-readme.txt $1-readme-tr.txt
      fi
    

    All these are free for use, and both are under GPL2. I can offer SOME support, but they’re filed under ‘Works for me!’ in my bin.