Adaptive Images in HTML »
via @devinsays A small package of PHP + JS that “Automatically adapts your existing HTML images for mobile devices. No mark-up changes needed. Just drop it in and forget about it.”
Managing News »
A “robust news and data aggregation engine with pluggable visualization and workflow tools.” Open source and based on Drupal.
Managing News »
A “robust news and data aggregation engine with pluggable visualization and workflow tools.” Open source and based on Drupal.
WordPress Snippets »
A collection of WordPress snippets to make developers' lives just a bit easier. I'm not found of the current UI as it's not easy to skim, but the filter capability helps and I'm sure the site will improve as it grows.
Tweet Nest »
Finally, an easy way to have a browsable and searchable archive of your tweets. Even better, you can host it on your own site. Hat tip to @rands for the link.
MacGDBp: A Remote PHP Debugger for OS X
Blue Static has released MacGDBp, “a native Cocoa application that allows Web developers to debug their PHP applications.” The tool utilizes the Xdebug PHP extension to connect to the running PHP app so the developer can step through their code, add breakpoints and see the local variables and function call stacks all within an OS X interface.
I can’t wait to try the app, though I do wish they would have chosen a name that is a bit more pronounceable.
Fixing the WordPress Theme Reset Problem
As I posted in the WordPress forums I’ve run into an odd problem – WordPress occasionally resets my theme to the default version, which is annoying to say the least. After a lot of digging, I learned that the likely culprit is a bit of code in WP meant to protect the user from bad themes, but which has had the opposite effect for me and many other users. Luckily, others have already reported the bug and filed a patch, but the fix won’t be released until the next version of WordPress (2.4), which is slated for late January.
So, I decided to go out on a limb and make the change in my local version with the expectation that the file will be overwritten when I upgrade to the latest and greatest. So, I modified one line as indicated in Changeset 6325, commenting out line 269 of wp-settings.php, which contained validate_current_theme();.
I’m not positive that this will fix the issue, but all of the signs point in the right direction. As the fix is simple, and has been made to 2.4, I feel relatively confident that it is a safe move on my part. I’ll keep an eye on my site and post updates as needed.
Many thanks go out to the great folks constantly improving WordPress!
Update: Well, that theory didn’t last too long. When I hit the site this morning my theme had reset. Grrr.
Cake on OS X with Headdress
As I’ve been testing CakePHP I’ve run into an odd issue on my local OS X development environment. I couldn’t get the system configured to properly render the site I was building. It didn’t even show the default documentation properly – the CSS and images were missing. After digging around the Web and trying many different options, including mod_rewrite modifications and changes to MAMP, I discovered that I hadn’t properly configured my local dev site in Headress.
The issue was my choice of document roots within Headdress. I had chosen the main directory (Dev/MySite/), but what I needed to choose was the webroot directory a couple of levels down (Dev/MySite/app/webroot/). That small change fixed the appearance and redirection issues. Easy as Cake!
Quick Note to My Future Self: PHP & Memory
When WordPress or another Web app starts throwing fits and kicking out fatal errors due to memory, make sure the local php.ini (same dir as the scripts) is allocating enough RAM. 8Mb is not nearly enough.
Style Evolution – Dynamic CSS Part 2
Please note that this assumes you have read Part One of the series.
Also, I have taken to calling this Evolved CSS, as the word “dynamic” is a bit too close to the old days of DHTML (Dynamic HTML) for my liking. Let’s jump right in shall we?
Files
Download this zip file if you would like to see a running example of this project and/or have a foundation for your experimentation.
Reduce Server Calls Without Sacrificing Ease of Maintenance and Organization
Web Developers follow many practices in their organization of style sheets. Some put everything in a single document, while others create separate style sheets for each of their major page types or templates. In addition, most seasoned professionals make use of a style sheet that resets all the browser rules (see Eric Meyer’s version) to make life easier.
And..?
Well, if you’re in the practice of using multiple style sheets, your sites may be taking longer to render than they need to, no matter how compressed your CSS may be. This is due to the fact that the browser needs to communicate with the server to snag each individual document, and most browsers only allow a few connections at a time. As noted on the Yahoo UI Blog, a lot of performance issues are directly related to front-end engineering. That’s actually a big win for those of us on the front-end as we don’t have to shell out for better servers or faster pipes. We can simply improve our code to make life easier for our users.

Their four-part article on reducing HTTP requests is lengthy, and may contain more details than you you’ll care about, so to break it down, here’s the key point in regards to this write-up: “Reducing the number of HTTP requests has the biggest impact on reducing response time and is often the easiest performance improvement to make.” In the context of Evolved CSS, we can make a large impact by using PHP/ASP/JSP et al to take all of our style sheets and combine them into a single document.
The code
For this example, let’s assume your site has the following set up:
- reset.css – Resets all styles to eliminate browser inconsistencies
- core.php – Includes the global layout rules (navigation, header, content area etc.) and text formatting
- scheme.php – The colors and images used for your site, this could easily be a script that provides the end-user the ability to choose their own colors.
- home.css – Home-page specific layout/formatting rules.
- archive.css – Layout and formatting rules for your archive pages.
- gallery.css – The rules used to display your photo gallery.
- print.css – Defines the layout for the page when it is sent to a printer.
You may have noticed the combination of PHP and CSS for those file types – you can easily use either as Part One demonstrated, but keep in mind that you should use flat CSS files over PHP where you are able to reduce the time required to process and render the final style sheet.
Section-Specific vs. the Kitchen Sink
Evolved CSS works well with the practice of using a single global style sheet to define your general layout and styles and section-specific style sheets to serve up rules that are unique to different areas of your site, as you can pass parameters to your main style sheet in order to define which style sheets to include. The Browser will still cache it. Here’s an example of how you could pass these parameters, in this case pulling in the styles for your gallery and a blue color scheme.
<link href="/css/style.php?include=gallery,blue-scheme" rel="stylesheet"
type="text/css" media="screen" />
The file styles.php includes this code to take those parameters and pull in the appropriate style sheets:
/* -=-=-= Import Styles =-=-=- */
// Grab the parameters clean them up and add them to an array
$cssToInclude = split(',', makeSafe($_GET['include']));
/* -=-=-= Core Styles =-=-=- */
// Core will be included every time
include_once 'core.php';
/* -=-=-= Additional Styles =-=-=- */
// Check the array to determine which style sheets to include
if (in_array('home', $cssToInclude)) {
include_once 'home.css';
}
if (in_array('gallery', $cssToInclude)) {
include_once 'gallery.css';
}
if (in_array('archive', $cssToInclude)) {
include_once 'archive.css';
}
That’s all You Need to Start
Well, this is a pretty short example, but I think it gets the poitn across and sheds some light on the possibilities available to you when you harness the power of server-side scripting languages to serve your CSS.
Note: This code is for example purposes only – it could be a lot cleaner, but at this point I am keeping it simple for explanation’s sake. I’m including the function makeSafe() to clean up the parameters. You can see the code in styles.php, contained in the source file package, if you are curious about it.
A Word on Media Types
This practice can only be used style sheets of the same media type – do not merge your screen style sheets with your print styles or you will get all sorts of ugliness.
What about priority and inheritance?
That’s a damn fine question! At this point, this structure works exactly the same as using multiple style sheets does. Most browsers will use the last rule defined, but you shouldn’t rely on that. As a good developer you should know where your conflicts may be and resolve them intelligently. The !important declaration can be used where needed to resolve specific conflicts.
Conclusion
Well, that about wraps it up for today kids, thanks for reading! Please leave your comments, suggestions and/or questions as I would love to expand the discussion. Also, I would love to hear your thoughts on what I should address next.
Future Evolved CSS Topics
- Let the server do the math – auto-generating widths for your grid
- Using Evolved CSS to improve debugging
- CSS Compression
Dynamic CSS A.K.A. CSS Variables
Cascading Style Sheets are an amazing tool, having transformed Web Design as an industry and the Web as a communications medium. But in all of its glory (and it is glorious), CSS has some flaws. The most frustrating for me is its static nature. I want to be able to reuse values (CSS variables if you will), I want to make use of browser detection instead of CSS hacks, or IE’s proprietary conditional comments and I want to use logic to serve up specific rules in certain situations. Enter PHP (or your server-side langugage of choice), which will provide us a wealth of new options for working with our CSS, including the ability to adapt to our end-users’ needs.
Hello…. JavaScript Can Do That Already!
Yeah, client-side scripting can handle most of these requirements, but I don’t want to rely on a technology for my presentation that can be disabled by the user or their corporate IT department and frankly the JS support of mobile devices is poor at best. Enter server-side languages, which cover all of these bases without impacting the program or device rendering the site.
What I’ll Cover
- The Initial Setup
- Serving a Dynamic (PHP) File as CSS
- Useful Variables and Practices
- Implementing Browser Detection to Avoid CSS Hacks
- Putting it All Together
- Too Much Considered Harmful
- Acknowledgments and Sources
- Your Turn
The Setup
This article assumes that you have a Web server at your disposal that is running one of the aforementioned scripting languages and that you have a basic understanding of scripting in that language and know a bit about CSS. For the purpose of this write up I’ll be using PHP, but I have implemented versions of this system on production sites running JSP, and there’s no reason the same couldn’t be done with Ruby on Rails, Python, ASP or any other server-side solution.
This system can be as detailed or relaxed as you’d like, so I’m going to keep this write-up relatively simple with a few interesting bits thrown in. If it proves to be an interesting subject I’ll write a follow-up showing advanced usage. Let’s hit it!
Serving a Dynamic (PHP) File as CSS
In your editor of choice create a new PHP file. I’m calling mine styles.php. Paste this line at the very top of the document:
<?php header('Content-type: text/css'); ?>
This tells the server that the page should be sent to the browser as a CSS document, so the file won’t need the .css extension. All of our work will be done in this bad boy. So, on to the next step.
Useful Variables and Practices
So, we have a PHP file that has a serious personality disorder, thinking that it’s a style sheet. What the hell are we going to do with it? Well, we’re going to set a few key variables that will make life much easier. Specifically, we’ll set variables for common measurements (columns, containers and the space between) and some colors from the site’s palette:
$gutter = '10px'; /* Used to separate visual blocks */
$pageWidth = '1000px'; /* Width of the Web page */
$pageWidthPadded = '980px'; /* $pageWidth minus padding ($gutter x 2) */
$col1 = '800px'; /* Width of the main content area */
$col1Padded = '780px'; /* $col1 minus padding ($gutter x 2) */
$col2 = '180px'; /* Width of the sidebar area */
$col2Padded = '160px'; /* $col2 minus padding ($gutter x 2) */
$lightGray = '#e5e5e5';
$charcoal = '#464646';
$orange = '#f60';
$darkBlue = '#0059b2';
The width variables will prove useful in creating a site as they guarantee consistent presentation from page to page and template to template. This model can easily be extended for multiple column widths, so if you want to subdivide Column 1, you only have to set it up once, creating the variables ($col1A, $col1B etc.) and setting their values to the appropriate widths. For you folks who love them grids, this should make life pretty easy.
Setting up color variables simplifies the initial site build-out and future revisions. When you return to the style sheet six months from now, you’ll notice $darkBlue is much easier to remember than #0059b2.
So, now that we have width and colors, it’s simple to use these new variables in the style sheet, all you need to do is use PHP’s echo shortcut (<?= 'print this' ?>):
#Wrapper {
background-color: <?= $lightGray ?>;
border 1px dotted <?= $darkBlue ?>;
margin: <?= $gutter ?>;
width: <?= $pageWidth ?>;
}
Advanced: I’ve begun to separate the measurement value (px, em, pt) from the actual numerical value so I can harness the power of PHP to do my math for me. That’ll be the subject of a future write-up.
Implementing Browser Detection to Avoid CSS Hacks
I’ve used a couple of different packages in the past; at the moment I use BrowsCap, which covers these needs nicely, but use whatever fits your needs best. Place this code at the top of styles.php, after the PHP header line:
require_once('Browscap/Browscap.php');
// Create a new Browscap object (loads or creates the cache)
$bc = new Browscap('Browscap/cache/');
// Get information about the current browser's user agent
$current_browser = $bc->getBrowser(null,true);
$browser_platform = $current_browser['Platform'];
$browser_name = $current_browser['Browser'];
$browser_ver_major = $current_browser['MajorVer'];
$browser_ver_minor = $current_browser['MinorVer'];
$browser_ver_full = $current_browser['Version'];
$is_ie6 = false;
$is_ie7 = false;
$is_safari = false;
$is_ff = false;
if ($browser_name == 'IE' && $browser_ver_major == 6) {
$is_ie6 = true;
} elseif ($browser_name == 'IE' && $browser_ver_major == 7) {
$is_ie7 = true;
} elseif ($browser_name == 'Firefox') {
$is_ff = true;
} elseif ($browser_name == 'Safari') {
$is_safari = true;
}
So we now have a few variables that will allow us to quickly determine whether the user’s browser is IE 6, IE 7, Firefox (any version) or Safari (any version). You can extend this model to fit your specific audience and needs.
Putting it All Together
Sweet, now we can rock the styles all dynamic-like! Here are a couple of examples for you to nibble on:
body {
<? if($browser_platform == 'MacOSX') { ?>
font: .85em/1.4 normal "Lucida Grande", Verdana, sans-serif;
<? } else { ?>
font: .75em/1.4 normal "Lucida Grande", Verdana, sans-serif;
<? } ?>
That block outputs a larger font size for folks who are on a Mac compared to folks on PCs or other devices.
The next one modifies the value of a top margin, serving up 5px for IE 6, and zero for all other browsers.
#NavWrapper1 {
display: block;
height: 18px;
<? if ($is_ie6) { ?>
margin-top: 0;
<? } else { ?>
margin-top: 5px;
<? } ?>
margin: <?= $gutter ?>;
width: <?= $pageWidthPadded ?>;
}
Advanced: This method can be used to detect alternate browsers as well. So, you could detect a mobile browser and serve up a separate style sheet. Or if you detect a screen reader you could serve up a style sheet with proper aural rules defined.
That’s it, we’re rolling with dynamic CSS, harnessing the power of both PHP and Cascading Style Sheets. There is a lot more that can be done, but I hope this opened a few avenues for experimentation on your future projects.
In Moderation: Too Much Considered Harmful
It would be really easy to overuse this method. Do not try to replace proper use of grouping and the cascade with PHP. You won’t gain anything but frustration and larger style sheets. Take the time to think through the variables that you are going to create to make sure they make sense and are not simply recreating existing CSS functionality.
Acknowledgments
I am by no means the only person to think of this, there are many others who have covered the topic on their sites, but I felt that there were a few components missing, so here we are. I hope I added to your toolbox. It is also very important to note that there are some great folks with whom I’ve worked who have expanded on the concept and helped me flesh it out to be a viable and reusable tool in the Real World ™, most notably the inestimable Leesa of Red Velvet Cafe.
Your Turn
I look forward to your feedback and questions, so please leave a comment.
Ma.gnolia Plugin 1.4 Released
Thanks to Rick and Emre for the excellent suggestions which prompted these improvements to the Ma.gnolia WordPress plugin:
- Added the ability to pull bookmarks from group collections as well as those of individual people. Tags can be used with either, so you can pull bookmarks from the Web Design group that have been tagged with ‘css’.
- Added ability to pull the Full feed from Ma.gnolia, which includes:
- Thumbnails of each bookmark
- The tags applied to each bookmark
Please note, this is all or nothing, so you cannot just pull the image, or the image and description without the tags. Sorry, but that’s how it’s coming through and I spent too much time trying to find a way around it with a couple of different RSS parsers.
- Changed the variable $username to $collection to fit the new model of pulling from groups or individuals. This shouldn’t impact your site as it is more of a clean-up task.
- Added configuration option to enable/disable the link to view more Ma.gnolia bookmarks
- Added the plugin to wp-plugins.net/ to ease updates for folks using Update Manager to track plugin updates (like me).
Please check out the official page to download the latest version and the new examples page to learn more about the plugin.
Note: for Users of 1.3: You should be able to drop this upgrade in place without changing any of your code. Please let me know if you notice any issues with your existing setup.
The New Ma.gnolia WordPress Plugin
Barry Price, the creator of the Ma.gnolia plugin for WordPress has set its development aside and has encouraged me to adopt the project. As I use the plugin heavily on this site, and I enjoy development, I decided to take him up on it.
This plugin makes it easy to output a list of your Ma.gnolia bookmarks anywhere on your site. You can set it to only pull bookmarks with a specific tag, which is great for listing sites related to a specific category or post.
Please download the plugin and provide me your feedback in the comments of this page. I’ll do my damnedest to fix any bugs you report and look forward to expanding it to be even more useful!
Update
I’ve updated the plugin. Please go to the official page for the latest version: Ma.gnolia Plugin.

Magnolia WordPress Plugin
Make sure to join the Plugin group on Ma.gnolia to add your site to the list if you are using this plugin!
Install
- Drop the entire plugin folder into wp-content/plugins/ – the final paths will be:
- wp-content/plugins/magnolia/last_rss.php
- wp-content/plugins/magnolia/magnolia.php
- Activate the plugin in the admin area of your wordpress install
To Use
This plugin is very basic at the moment, so all it takes once you’ve installed the plugin is a single line of PHP, inserted wherever you want the list of links to appear. You can pass the following variables to the plugin:
- $username is the Ma.gnolia account to use, this is typically your account.
- $numLinks sets the amount of links you want the tag to output, this defaults to 10.
- $showDescriptions tells the tag whether or not it should include descriptions in the output. This defaults to “Do Not Show”.
- $showPubDates tells the tag whether or not it should output the date the URL was bookmarked in Ma.gnolia. This defaults to “Do Not Show”.
- $useMagnoliaLinks determines whether the links should point directly to the bookmarked URL, or the bookmark’s page on Ma.gnolia. This defaults to the Bookmark’s actual URL.
- $tag allows you to pass in a tag to narrow down the list of results. Only bookmarks matching that tag will be output. This is empty by default, so it pulls all bookmarks regardless of their tags. Use a plus sign (+) to separate multi-word tags. For example “web+design”.
The output consists of an unordered list, each link contained in a separate list item tag.
Example of Usage
Here’s a snippet to output three bookmarks, with their associated descriptions from my bookmark list, regardless of the tag.
<?php magnolia('BaldTechnologist',3,1,0); ?>
Example Output
<ul>
<li><a href="http://www.flickr.com/photos/17328648@N00/sets/1737284/" title="Cool & Wacky Records - a photoset on Flickr:: No Description" class="ToolTip">Cool & Wacky Records - a photoset on Flickr</a></li>
<li><a href="http://www.fortymedia.com/blog/post/59" title="Attention Mapping: The 10-Point Exercise:: Attention is the most fundamental unit of design. Once you get past the color schemes, typography, layouts, graphical treatments, etc., it all comes down to guiding and shaping the viewer’s attention." class="ToolTip">Attention Mapping: The 10-Point Exercise</a></li>
<li><a href="http://haha.nu/misc/html-tags-illustrated/" title="HTML Tags illustrated:: A collection of photos that demonstrate HTML tags." class="ToolTip">HTML Tags illustrated</a></li>
<li class="MagnoliaLink"><a href="http://ma.gnolia.com/people/BaldTechnologist/bookmarks" title="Alex Jones on Ma.gnolia::Browse through the sites and pages that I have added to my bookmark list on Ma.gnolia. If you're a member, add me as a contact!" class="ToolTip">View my bookmarks on Ma.gnolia</a></li>
</ul>
Other Examples
Five Bookmarks Tagged with “Design”, No Descriptions, Pointing to the Original URL
<?php magnolia('BaldTechnologist',5,0,0,0,'design'); ?>
Ten Most Recent Bookmarks with their Descriptions and the Time they Were Saved to Ma.gnolia, Pointing to the Link’s Ma.gnolia URL
<?php magnolia('BaldTechnologist',10,1,0,0,'History'); ?>
Behind the Scenes
Barry Price built the first version of this plugin, and what you see here is a a modified version of his work the Last RSS Parser, which does much of the heavy lifting. At this point, Alex (BaldTechnologist on Ma.gnolia) has picked up the project and will be adding features as suggestions come in and time allows. If you have an idea, please contact me and I’ll see what I can do!
Contribute, for Free!
It’s easy to support this free plugin, and it won’t cost you a thing! Here are a few simple ways:
- When you plan to buy something from Amazon, follow this link (Amazon.com)
. It won’t cost you anything, but it will add a small amount of your purchase to my account.
- Write about the Ma.gnolia for WordPress plugin on your site
- Add a link back to my site (www.silverspider.com) from yours
- Drop me a line to say hi and let me know where you are running the plugin.
Changes Made
I’ve made some changes, both major and minor to the plugin, including:
- Changed quote usage from single quotes to double quotes to improve parsing efficiency.
- Improved comments within the script
- Moved the feed parser class (Last RSS) to a separate file for ease of maintenance.
- Various code, formatting and commenting changes
Upcoming Changes
These are not currently prioritized, but I want to add these features/implement these revisions:
- Add CRON abilities to pre-cache feeds instead of waiting for a request
- Add ability to search multiple tags (AND & OR)
- Add the ability to pull from groups in addition to by tags
- Documentation with some examples
- Improve configuration options
- …(this is where your suggestions come in)
Change the Thesis Doctype and Add Meta Tags
I love using Thesis because it lets me focus on content, while providing all of the design and development hooks I need to tweak the theme as I see fit. I’ve dug in a good bit, and while I’m far from an expert, I’m confident that anything and everything I want to do is available to me.
One thing I discovered early is that the default doctype is XHTML Strict, which is great in many respects, but can add some complexity given enough design changes and external data sources.
In 1.6 I was able to add some custom code to change the doctype to XHTML Transitional, simplifying some issues I was having with IE 8. Those same reasons necessitated that I include a new meta tag as well. Thesis 1.7 changed the implementation methods, so I’m documenting the new, right way to modify the doctype and add items to the page head in the hope that others might find it useful.
Credit: I learned about of this from girlie, who was kind enough to point me in the right direction on the Thesis forums.
Modify the Thesis Doctype
Simply add this to custom_functions.php in your Thesis directory:
Adding Meta Tags or Conditional Comments
This hadn’t occurred to me as I’m used to placing these directly in the code, but once girlie pointed me in the right direction I found it is a simpler solution.
<head>Thinking About Thesis?