Archive for the ‘Coding’ Category

Open Sessions in PHP

Wednesday, February 1st, 2012

I’ve spent many years with PHP, and one of the most surprising problems I see, made not only by developers but even by PHP frameworks, is in how they handle sessions. More specifically, how they handle closing a session. It’s such a core concept to PHP development that I would have at least expected some of the frameworks to provide options around closing sessions on the fly, but alas even Zend seems to think the best thing to do with session is open it and keep it open for the entire thread.

Indeed in many circumstances keeping it wide open is the best thing to do, since opening and closing a session file will require disk access (unless session is configured in non-default manners, and stored in a database) and disk access is slow. If your web application does not rely much on asynchronous calls, but on full page reloads, then it’s easy enough to go with the flow: open your session and close it at the end of thread execution. But this is the year 2012, if you’re website can’t support at least some level of AJAX I’m not sure you’re doing it right.

If your application even runs a few things at the same time, you could benefit greatly from keeping sessions closed until they are explicitly required. Essentially, if you keep the session open, no asynchronous threads can grab onto the session file until the first thread completes. Asynchronous calls become quietly sequenced (which is pretty bad) and can dramatically increase overall load times.

Here’s an example of the problem, using Prototype on the client side to run to two supposedly asynchronous calls at the same time:

 

The result: Firebug shows us that even though the bar function should be pretty instant (since it doesn’t sleep like foo), it waited the entire 5 seconds for foo to finish:

Bar took 5.02 seconds!

 

The culprit is the first line, “session_start()”. What’s happening here is this:

  1. A request with function ‘foo’ begins a new execution thread (we’ll call it “Foo Thread”)
  2. Foo Thread calls session_start(). This opens the user’s session file for reading and writing, and locks the file
  3. A request with the function ‘bar’ begins a new execution thread (call it “Bar Thread”)
  4. Bar thread calls session_start(), but the file is currently locked by Foo Thread. Bar Thread now has to wait until Foo unlocks the file
  5. Foo Thread finishes sleeping, and ends execution. PHP automatically calls session_write_close() when the thread is complete
  6. Bar can now open the session file, quickly echo’s “bar” and exits

 

The easiest way to solve this is to keep the session closed until you need to write to it. At the most basic level, do this:

 

There are obvious problems that may arise with this approach, however, so I would not recommend closing the session wildly. Essentially, if anyone ever changes $_SESSION paramaters without first re-opening session by calling session_start, the change is lost when the thread ends execution. Calling session_start after making a change removes that change. I suspect this is the main reason most people leave it open all the time – managing opening and closing it over and over isn’t at all practical.

There is also the possibility that your copy of $_SESSION could become out of date, as an asynchronous thread updates values in the session file your on-hand $_SESSION array doesn’t know about. It won’t be updated again until session_start is called, which could potentially be problematic if your code relies on the absolute, most recent state of session for critical functions. Realistically many applications simply won’t find this limitation all that daunting, but it’s certainly something to keep in mind.

 

But these two problems alone shouldn’t deter you. The execution time saved can be tremendous, and there is a deceptively clean way to properly manage your session in a large application: don’t ever call $_SESSION directly. Create your own class to mange $_SESSION, or use a framework like Zend Session to manage it for you (but note, Zend Session doesn’t close the connection automatically either, you’ll have to use a wrapper class to trigger that automatically).

-Andy

Add Nauseam

Wednesday, April 7th, 2010

So a quick shout out to any Javascript programmers. Please note that Javascript can’t add, multiply, subtract or divide. Let me repeat that for you: Javascript can’t add, multiply, subtract or divide.

I know it sounds implausible that the base code for all web browsers (ie. the internets) can’t do basic math. But I’ll prove it too you. Open up your “Error Console” (Firefox’s Tools->Error Console) and type the following basic math, followed by enter:

1.519+0.075

The Result:

Yep, according to Javascript, 1.519+0.0750 = 1.593999999999 (for all the math wizards out there, the correct answer is just 1.594).

I don’t want to hear those “Javascript Apologetics” out there blame something else, like the ways floating point numbers are calculated or that it’s the browser or whatever — if I were to design a programming language of any quality at all, Requirement #1 would be “can do basic math.” This imperfect result is in no way useful to me. I can’t even round it back to the right number reliably since the fractional inaccuracy isn’t consistent.

There is a solution, albeit an asinine one (since you really, really, really should NOT have to deal with this in the first place) but if you convert the number to a pure integer, do the math, and then convert it back to a decimal, then it all comes out mathematically correct.

Observe, the solution:

Math.round((1.519*Math.pow(10,3) + 0.075*Math.pow(10,3)))/Math.pow(10,3);

Yes, all of that to just add two numbers and get the correct result. To break it down:
  1. Math.pow is a way to do exponents. First argument is the base, second the exponent. So Math.pow(10,3) is the same as 10 ^ 3 (which equals 1000).
  2. The 1000 is then multiplied to each number: 1000 * 1.519 + 1000 *  0.075
  3. The result is 1519 + 75. Since these are whole integers, Javascript won’t do any fancy calculation-ruining floating point math. The result is simply 1594.
  4. Math.round will cut off any trailing decimals (though I’d recommend you just increase the precision with Math.pow instead).
  5. Now it will divide by 1000 to get it back down to a decimal: 1594 / 1000 = 1.594

There we go! We now skirt the whole floating-point error issue by using whole number arithmetic! It’s just that easy! Call now, and you all receive subtraction AND multiplication at no additional charge!

Subtraction:
function addNumbers(num1, num2, precision){
return Math.round((num1*Math.pow(10,precision) – num2*Math.pow(10,precision)))/Math.pow(10,precision);
}
Multiplication:
function multNumbers(num1, num2, precision){
Math.round((num1 * num2)*Math.pow(10,precision))/Math.pow(10,precision);
}

That is all. </rant>

-Andy

Fox News 120% Awesome

Wednesday, December 9th, 2009

FoxNews admittedly fiddled with some of their own poll numbers to fit results from a survey with 5 questions into 3 categories. Unfortunately they double counted a few items, and ended up with results that totaled over to 120%:

fox.rasmussen

This doesn’t even count the 15% that  said they weren’t sure. Genius.

FoxNews “Fair and Balanced?” Usually, ‘fair’ means not skewing the “somewhat likely” to show results that align with your skewed perceptions. And a ‘balanced’ equation is not 56 + 35 + 26 + 15 = 100. The real joke – the executive producer LaurenPetterson explains it wasn’t an error, “We didn’t put on the screen that it added up to 100 percent.”

Oh yeah well that’s true. Hmm, perhaps it would have been clearer as a simple pie graph:

foxnews

135% Bullshit

[via reddit]

-Andy

DOM You Safari!

Thursday, September 10th, 2009

I was checking on my post yesterday, the one about preventing Spam comments in WordPress - and happened to use Safari instead of my normal Firefox. In general I almost always use Firefox since, as a web developer, it’s just easier to code with. It’s more forgiving in general, and more accurate in its interpretation of HTML, CSS, and JavaScript (in my experience) than Safari (and especially more accurately than IE).

When things do seem to go wrong, it is more often in the complicated pieces where I’m trying to use some neat code trick or something. Quite frequently, a trick will work just fine in Browser A but not work at all (or worse, simply work differently) in Browser B. I’m not accustomed to is seeing, however, simple plan-text vanilla-flavored HTML just not be parsed correctly in the first place.

Take, for example, this code:

<div id="quickSummaryfull">
     <p class="p6">
          <span>&nbsp
               <div class="alignleft">&laquo; <a href="http://andyhoffner.com/?p=130">
                   (Re)Building A Blog-based Website From (Near) Scratch – Part 2</a>
                </div>
                <div class="alignright"></div>
           </span>
     </p>
</div>

This sample is taken from the little backwards/forwards links at the top of each post on this site (the ones with the dotted underline). If you looked at this site in Safari prior to this post, you’d have noticed the formatting of this was off. The links rendered below the dotted line, instead of above it. Why? Safari couldn’t parse the </span> or </p> tags correctly, so it closed the “class p6” item prematurely and threw away my spans entirely.

For the sake of conversation, I’ll simplify the problem down to this (which still causes the bug):

<div id="quickSummaryfull">
     <p>
          <div>Link to the older post!</div>
          <div>Link to the newer post!</div>
     </p>
</div>

For the layman, this structure is a “div” (just a containing element, think of it as a box of some size), a “p” (or paragraph element) which contains two more “divs”. In the DOM, it should look like this:

  • div #quickSumamryFull
    • p
      • div – Link to the older post!
      • div – Link to the newer post!

This is how it renders in good ol’ Firefox! But in Safari, it renders like:

  • div #quickSumamryFull
    • p
    • div – Link to the older post!
    • div – Link to the newer post!

See how the div’s are at the same level as the p? This is why they render below the dotted line, not above it. Safari isn’t doing this without reason, however, if you use Safari’s nifty “Resources” Panel (right click on the offending item, and select “Inspect Element”, you’ll then click Resources, and then the button to Enable it) – you’ll notice two errors:

Safari DOM Errors

From the real code at the start (the one with the spans)  it can’t seem to figure out why there is a closing span </span> or closing p </p> element in the code. But there should be – I opened a p and a span just two lines up.

Even if you delete the spans (like in the simplified example) it still can’t make heads or tails of the closing p tag. Why? No idea. It’s not logically complex code – maybe it isn’t perfectly “to spec” (it might be, the million page HTML specification document is only readable, I think, by those who posses some kind of ancient, lost cryptex)  but honestly if it not valid, then it should be. There is no logical reason these simple elements should be ‘nestable’. You can nest divs in divs, why not divs in p’s?  It also works just fine in Firefox. It also works fine if you change the code to simply use spans instead of divs:

<div id="quickSummaryfull">
     <p>
          <span>Link to the older post!</span>
          <span>Link to the newer post!</span>
     </p>
</div>

Now Safari can figure this code out. It’s barely different – and frankly I’m now just left unimpressed by the DOM parser built into Webkit.

I’m not the only one to notice some unexpected behavior in how browsers render DOM elements – take this post from Hixie Natural who also noticed some lovely cross-browser inconsistencies when writing the HTML 5 Specification. The conclusion – they pretty much do whatever the hell they feel like, and generally regardless of the specifications. And sometimes, they get lucky.

-Andy

SPAM – The Other Grey Meat

Wednesday, September 9th, 2009

A quick follow up note in regards to my last post, where I described in gory detail how to convert a customized layout into a WordPress-powered blog. WordPress does open up a very rich feature base for both you and your readers, but it also opens up your blog to a lot of spammers and bots which have evolved to take advantage of the comments and registration systems that are common to all WordPress-enabled sites. What this means is that eventually your blog will be found out, and bots will start trying to insert all kinds of crap into your comments area on each post. There are several ways to combat these Decepticons, and by combining multiple methods you can prevent spam with just a few minutes of work.

The first and most simple way is to ensure your WordPress moderation settings are adequately restrictive. Check out the Settings-> Discussion page in the Admin panel.

Check at minimum:

  • Comment author must fill out name and e-mail
  • Comment author must have a previously approved comment

All the settings in this section are pretty self-explanatory, but these two are particularly important first steps to securing your comment system. This will, at the very least, let you set up spam lists (by tracking emails) and prevent new users’ comments from automatically appearing on your posts. This way, guests that frequently comment are assumed to be “Approved” and don’t need to wait for moderation, but new people, which might be spammers, must first have their comment moderated.

This is a good start – but it produces a new problem. When spammers start trying to comment, you will be required to mark all their responses as spam. This can become particularly annoying when you get 5 or more spam comments a day – and it gets downright frustrating when that number starts to spike to 10 or 20 or 30…

What the hell is a 'smwm'?

One of the most common ways to reduce this number is to install a plugin like CAPTCHA. This will place one of those little images with a difficult-to-read phase in it. This will instantly defeat any automated bot – but I generally dislike these for the simple reason that, by design, they’re difficult to read. For a casual blog, it’s going to be hard to get anonymous commenters to say something if they can’t read the little CAPTCHA image on the first try. Maybe if your blog gets some serious traffic, then a plugin like this would be more warranted, but honestly for a mom-and-pop operation like this one, CAPTCHA is just downright annoying.

There are a lot of alternatives to CAPTCHA systems, however. One of the most popular and lightweight is the aptly-named Anti-Captcha. This plugin won’t change the look-and-feel of your comments system at all – its magic is completely invisible. It plugin basically inserts a unique invisible token in your comment system. Since most automated bots don’t usually bother to check for it, they will usually neglect to send it along with their comment. If the token doesn’t get sent, this plugin automatically marks the post as spam. You’ll never have to even bother moderating it.

Anti-Captcha is a nice, lightweight solution for lightweight blogs, but for ones with heavier or even moderate traffic, I’d try something like WP-Spam-Free. Some bots are designed to look for tokens hidden by plugins like Anti-Captcha, since these tokens are very easy for smarter bots to find. WP-Spam-Free uses a similar concept (hidden tokens) but in a much more advanced way. Instead of just one hidden token the HTML form, where it can be easily scraped,  it actually hides them in JavaScript and Cookies, where bots have a hard time digging them out. The result is even fewer spam posts for your to moderate.

Wp_spam_free_screencapWP-Spam-Free also has some additional settings, letting you blacklist certain IP’s, URL’s, or e-mails from ever commenting again. It also has some more advanced logging features to help you fine-tune your settings or even recover auto-blocked comments. It can also be used to easily disable proxy-based comments, a tactic frequently used by spammers to block their IP but almost never used by readers of small blogs. I should note that by default it places a link to their site under your comment field. If you feel like supporting them, you can leave it, but you can turn it off in the settings if you’d like to keep your comment box clean.

If you feel compelled, you could even install both of these plugins, they can run side-by-side without conflicts, and will work overtime to keep out spammers.

The easiest way to install WordPress plugins is by logging into the Admin interface, and clicking Plugins from the menu on the left. Select Add New, then search for the plugin by name. Click the little Install link on the left, and enter in your site’s domain name and login credentials. If you don’t want to give out your creds so freely, you can install it manually by downloading the contents from their site, copying it to your remote web server, and placing it in the wp-conent/plugins/ folder. It will automatically show up in the Admin interface in the Plugins section, all you have to do is click the Activate link to turn it on.

With just minimal install effort up front, you can save a lot of time in the long run by keeping spam out of your blog entirely.

Happy hunting!

-Andy

(Re)Building A Blog-based Website From (Near) Scratch – Part 2

Sunday, September 6th, 2009

Building A Blog

Back in the early days of this blog, I didn’t have the luxury of programming languages like PHP to do a lot of the heavy lifting. I simply didn’t have the knowledge to use them – and even if I did, I was also severely limited by the servers that were hosting the content. They didn’t support server-side scripting or have databases for storing information. I had to maintain each page by hand, manually editing the content and shifting posts around as I wrote new ones. The process was tedious and required an inordinate amount of maintenance. The best thing to happen to this blog was to switch from static-content models, where I hand-crafted each page entry, to a dynamic model, that loads content stored from a database into pre-made shells. The advantages are numerous. Besides eliminating the need to meticulously manage content on every page, I can also automatically categorize, cross-link, and tag posts. End-users such as yourself benefit from features like searching across entries, a rich comment system, and a consistent user interface.

Unlike the “old days”, where server-side scripting was scarce, you’d be crazy in this day and age not to utilize some kind of blogging framework, or at minimum a scripting language with an underlying database. One thing I’ve learned, however, is that there is a fairly good gap between understanding a markup language (like HTML) and a programing language like PHP or JavaScript. If you’re relatively new to programming – and more used to drag-and-drop what-you-see-is-what-you-get (WYSIWYG) environments (like Dreamweaver)- then using these kinds of technologies can be a little intimidating at first. While I’m not going to give you a crash course in computer programming (at least not right now) – you don’t really need to have an extremely in-depth knowledge of the programming language just to get something put together. If you know HTML, then you probably already know more than you might think you know. You know?

If you already have a good layout  in HTML and CSS ready, then converting it from a static page of text into an interactive blog system is really not too difficult. Programming the system from complete scratch – starting with a blank page and an empty database is, however, a daunting task – even for a seasoned programmer. Taking advantage of a system like WordPress is far more practical, and it takes all the complicated pieces out of the equation. You don’t need to know how to program – you just need to know how to put all the pieces together.

Before I start the tutorial, let me briefly explain the big picture. WordPress is a PHP-based system. PHP code is executed on the server, pulls data from a database, and outputs HTML-formatted text. This HTML is then sent to your browser, which renders the page.

phptohtml

It can also output pieces of JavaScript, which run in your browser, and let you do things like connect to Facebook, or just validate a form. The goal, then, is to modify existing WordPress code to output HTML in you’re pre-designed format instead of their default format. These ‘formats’ are simply called Themes in WordPress. With just an hour or so of work, you can take your layout and a default WordPress Theme, and turn it into a highly-customized website.

It’s probably easier than you might assume. If you’re interested, just follow along below:

What You’ll Need

  • WordPress (http://wordpress.org/download/), v.2.8.4 or higher
  • Pre-made layout (See #3 for a good sample)
  • MySQL & PHP-Enabled web-server (I use MAMP locally, http://www.mamp.info/en/downloads/index.html. If you’re using Windows, you could use WAMP, but I’d recommend that instead you just stop right now and do what any right minded web-professional would do – go buy a damn Mac already. Seriously. Go ahead and run to the store – I’ll wait here until you get back.)

What To Do:

1. Download and install MAMP by dragging it to your Applications folder. Just double click it – and your done setting up a local website. The files are stored by default at ~/Sites/, and the website address is http://localhost:8080/. You also need to download and install WordPress, follow it’s instructions, as follows:

Original Ray’s “Famous 5-minute install”
1. Unzip the package in an empty directory.
Put this in your MAMP directory, like ~/Sites/wordpress
2. Open up wp-config-sample.php with a text editor like WordPad or similar and fill in your database connection details.
WordPad? Surely, they jest. If you like free, trying TextWrangler. If you’re serious about coding, Eclipse will do in a pinch, but it’ll pinch back. Recommended: Coda or BBEdit.
As for the Mysql DB credentials – the MAMP Homepage (http://localhost/MAMP/?language=English) will tell you what your credentials are.
3. Save the file as wp-config.php
4. Upload everything.
Actually, just do this locally first. Open up the page in a browser, aka http://localhost/wordpress and follow along. You’ll do this again on the webserver once we’re all finished. At a later point in time, consider adding version control systems like Git or SVN. I’ll cover each in a later tutorial.
5. Open /wp-admin/install.php in your browser. This should setup the tables needed for your blog. If there is an error, double check your wp-config.php file, and try again. If it fails again, please go to the support forums with as much data as you can gather.
6. Note the password given to you.
Did you ‘note’ it?
7. The install script should then send you to the login page. Sign in with the username admin and the password generated during the installation. You can then click on ‘Profile’ to change the password.
Please change the password to something good and secure, letters, numbers, symbols and all, and something you’ll actually remember.

2. Locate the Default theme: ~/Sites/wordpress/wp-content/themes/default. Make a copy of it, and rename it default_original.

3. We’ll edit the existing default theme. For reference, here is the layout I started with. I’ve highlighted how each section is going to be cut up, so you can see how the original code breaks down into the separate header, body, footer, and sidebar sections in WordPress.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head>
 <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
 <meta name="author" content="Andy Hoffner" />
 <meta name="keywords" content="andy hofner, hoffner, javascript, code, tech, apple, php, mysql, code samples, ramblings" />
 <meta name="description" content="The homepage of Andy Hoffner, programmer from Boulder Colorado. Focuses on coding, tech
  & video game news, and ramblings." />
 <meta name="robots" content="all" />

 <title>AndyHoffner.com - Home</title>

 <style type="text/css" media="all">
 @import "main.css";
 </style>

</head>

<body onload="window.defaultStatus='AndyHoffner.com';" id="andyhoffner">

<div id="container">
 <div id="linkList">
 <div id="linkList2">
 <div id="lselect">
 <h2>Articles</h2>
 <ul>
 <li><a href="/">Article 1</a></li>
 </ul> 

 <h2>Post Categories</h2>
 <ul>
 <li><a href="/">Category 1</a></li>
 </ul>

 <h2>Post Archives</h2>
 <ul>
 <li><a href="/">Archive 1</a></li>
 </ul>

 </div>
 </div>
 </div>

 <div id="intro">
 <div id="pageHeader">
 <h1>
 <li><div id='leftbkg'></div><div id='rightbkg'></div><div id='centerbar'></div>
 <div id='logotext'></div><span>AndyHoffner.com</span></li>
 <li><div id='tab1'></div><div id='tab2'></div></li>
 </h1>
 <h2><span>The Place You Go For Things</span></h2>
 </div>

 <div id="quickSummary">
 <p><span>There but for the grace of god...</span></p>
 </div>

 <div id="preamble">
 <h3 id='article1'><span>Building A Blog-based Website From Scratch</span></h3>
 <p>This is where the body text goes!</p>

 <h3 id='article2'><span>Basic Layered Layouts</span></h3>
 <p>This is also where body text goes!</p>
 <p><h4><span> -Andy</span></h4></p>
 </div>
 </div>

 <div id="footer">
 <a href="http://andyhoffner.com" title="Temp Link!">Home</a> &nbsp;
 <a href="http://andyhoffner.com" title="Temp Link!">Home away from home</a> &nbsp;
 <a href="http://andyhoffner.com" title="Temp Link!">no place like home</a> &nbsp;
 </div>

</div>
</body>
</html>

4. If you take a look at the default theme’s contents, you’ll see these pieces match up to files in there almost exactly, header.php, footer.php, sidebar.php and the body goes in index.php. The following steps will tell you how to take the code above and integrate it into each of these files.

5. First, open header.php. Remove all the lines in red. Add in the pieces from your header, which are in blue.

<?php
/**
* @package WordPress
* @subpackage Default_Theme
*/
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>

<head profile="http://gmpg.org/xfn/11">
<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />

<title><?php wp_title('&laquo;', true, 'right'); ?> <?php bloginfo('name'); ?></title>
<title>AndyHoffner.com - Home</title>
<link rel="stylesheet" href="<?php ">php php ">bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />
<link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" />
<link rel="stylesheet" href="wp-content/themes/default/main.css" type="text/css" media="screen" />

<style type="text/css" media="screen">

<?php
// Checks to see whether it needs a sidebar or not
if ( empty($withcomments) && !is_single() ) {
?>
#page { background: url("<?php bloginfo('stylesheet_directory'); ?>
/images/kubrickbg-<?php bloginfo('text_direction'); ?>.jpg") repeat-y top; border: none; }
<?php } else { // No sidebar ?>
#page { background: url("<?php bloginfo('stylesheet_directory'); ?>
/images/kubrickbgwide.jpg") repeat-y top; border: none; }
<?php } ?>

</style>

<?php if ( is_singular() ) wp_enqueue_script( 'comment-reply' ); ?>

<?php wp_head(); ?>
</head>
<body <?php body_class(); ?> onload="window.defaultStatus='AndyHoffner.com';" id="andyhoffner">
<div id="page">

<div id="header" role="banner">
<div id="headerimg">
<h1><a href="<?php echo get_option('home'); ?>/"><?php bloginfo('name'); ?></a></h1>
<div><?php bloginfo('description'); ?></div>
</div>
</div>
<hr />
<div id="container">
<div id="intro">
<div id="pageHeader">
<h1>
<li><div id='leftbkg'></div><div id='rightbkg'></div><div id='centerbar'></div>
<div id='logotext'></div><span>AndyHoffner.com</span></li>
<li><div id='tab1'></div><div id='tab2'></div></li>
</h1>
<h2><span>The Place You Go For Things</span></h2>

</div>

6. Now open up footer.php. Same deal, delete red, add your custom content in the blue. Little footnote here (pun intended) – removing the “Powered By WordPress” thing is optional – I just wanted to display it in a different place, and didn’t want the extra content mucking up the layout just yet. Please include it in your design wherever you feel warranted!

<?php
/**
* @package WordPress
* @subpackage Default_Theme
*/
?>

<hr />
<div id="footer" role="contentinfo">
<!-- If you'd like to support WordPress, having the "powered by" link somewhere on your blog
is the best way; it's our only promotion or advertising. -->
<p>
<?php bloginfo('name'); ?> is proudly powered by
<a href="http://wordpress.org/">WordPress</a>
<br /><a href="<?php bloginfo('rss2_url'); ?>">Entries (RSS)</a>
and <a href="<?php bloginfo('comments_rss2_url'); ?>">Comments (RSS)</a>.
<!-- <?php echo get_num_queries(); ?> queries. <?php timer_stop(1); ?> seconds. -->
</p>
</div>
</div>

<div id="footery">
<a href="http://andyhoffner.com" title="Temp Link!">Home</a> &nbsp;
<a href="http://andyhoffner.com" title="Temp Link!">Home away from home</a> &nbsp;
<a href="http://andyhoffner.com" title="Temp Link!">no place like home</a> &nbsp;
</div>

</div>
<?php wp_footer(); ?>
</body>
</html>

7. Sidebar.php – red = bad, blue = good, black = neutral. I pretty much have blown this whole file out, took a lot of content/features out with it – feel free to keep them if you like their look in your sidebar.

<?php
/**
* @package WordPress
* @subpackage Default_Theme
*/
?>
<div id="sidebar" role="complementary">
<ul>
<?php     /* Widgetized sidebar, if you have the plugin installed. */
if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar() ) : ?>
<li>
<?php get_search_form(); ?>
</li>

<!-- Author information is disabled per default. Uncomment and fill in your details if you want to use it.
<li><h2>Author</h2>
<p>A little something about you, the author. Nothing lengthy, just an overview.</p>
</li>
-->

<?php if ( is_404() || is_category() || is_day() || is_month() ||
is_year() || is_search() || is_paged() ) {
?> <li>

<?php /* If this is a 404 page */ if (is_404()) { ?>
<?php /* If this is a category archive */ } elseif (is_category()) { ?>
<p>You are currently browsing the archives for the <?php single_cat_title(''); ?> category.</p>

<?php /* If this is a yearly archive */ } elseif (is_day()) { ?>
<p>You are currently browsing the <a href="<?php bloginfo('url'); ?>/"><?php echo bloginfo('name'); ?></a> blog archives
for the day <?php the_time('l, F jS, Y'); ?>.</p>

<?php /* If this is a monthly archive */ } elseif (is_month()) { ?>
<p>You are currently browsing the <a href="<?php bloginfo('url'); ?>/"><?php echo bloginfo('name'); ?></a> blog archives
for <?php the_time('F, Y'); ?>.</p>

<?php /* If this is a yearly archive */ } elseif (is_year()) { ?>
<p>You are currently browsing the <a href="<?php bloginfo('url'); ?>/"><?php echo bloginfo('name'); ?></a> blog archives
for the year <?php the_time('Y'); ?>.</p>

<?php /* If this is a monthly archive */ } elseif (is_search()) { ?>
<p>You have searched the <a href="<?php echo bloginfo('url'); ?>/"><?php echo bloginfo('name'); ?></a> blog archives
for <strong>'<?php the_search_query(); ?>'</strong>.
 If you are unable to find anything in these search results, you can try one of these links.</p>

<?php /* If this is a monthly archive */ } elseif (isset($_GET['paged']) && !empty($_GET['paged'])) { ?>
<p>You are currently browsing the <a href="<?php echo bloginfo('url'); ?>/">
<?php echo bloginfo('name'); ?></a> blog archives.</p>

<?php } ?>

</li>
<?php }?>
</ul>
<ul role="navigation">
<?php wp_list_pages('title_li=<h2>Pages</h2>' ); ?>

<li><h2>Archives</h2>
<ul>
<?php wp_get_archives('type=monthly'); ?>
</ul>
</li>

<?php wp_list_categories('show_count=1&title_li=<h2>Categories</h2>'); ?>
</ul>
<ul>
<?php /* If this is the frontpage */ if ( is_home() || is_page() ) { ?>
<?php wp_list_bookmarks(); ?>

<li><h2>Meta</h2>
<ul>
<?php wp_register(); ?>
<li><?php wp_loginout(); ?></li>
<li><a href="http://validator.w3.org/check/referer" title="This page validates as XHTML 1.0 Transitional">
Valid <abbr title="eXtensible HyperText Markup Language">XHTML</abbr></a></li>
<li><a href="http://gmpg.org/xfn/"><abbr title="XHTML Friends Network">XFN</abbr></a></li>
<li><a href="http://wordpress.org/" title="Powered by WordPress, state-of-the-art
 semantic personal publishing platform.">WordPress</a></li>
<?php wp_meta(); ?>
</ul>
</li>
<?php } ?>

<?php endif; ?>
</ul>
</div>
<div id="linkList">
<div id="linkList2">
<div id="lselect">
<h2>Articles</h2>
<ul>
<?php wp_list_pages('title_li='); ?> <!-- This fetches a list of pages with an <;;li> tag without a headline -->
</ul>

<h2>Post Categories</h2>
<ul>
<?php wp_list_categories('show_count=1&title_li='); ?> <!-- This does the same -->
</ul>

<h2>Post Archives</h2>
<ul>
<?php wp_get_archives('type=monthly'); ?>
</ul>

</div>
</div>
</div>

8. Finally, the body:

<?php
/**
* @package WordPress
* @subpackage Default_Theme
*/
<?php get_header(); ?>
<div id="content" class="narrowcolumn" role="main">
<div id="quickSummary">
<p><span>There but for the grace of god...</span></p>
</div>
<div id="preamble">
<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<div <?php post_class() ?> id="post-<?php the_ID(); ?>">
<h23><a href="<?php the_permalink() ?>" rel="bookmark"
title="Permanent Link to <?php the_title_attribute(); ?>"><span><?php the_title(); ?></span></a></h23>
<small><?php the_time('F jS, Y') ?> <!-- by <?php the_author() ?> --></small>
<p>
<div class="entry">
<?php the_content('Read the rest of this entry &raquo;'); ?>
</div>
<p class="postmetadata"><?php the_tags('Tags: ', ', ', '<br />'); ?> Posted in <?php the_category(', ') ?> |
<?php edit_post_link('Edit', '', ' | '); ?>
<?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?></p>
</p>
</div>
<?php endwhile; ?>
<div class="navigation">
<div class="alignleft" ><?php next_posts_link('&laquo; Older Entries') ?></div>
<div class=alignleft"><?php previous_posts_link('Newer Entries &raquo;') ?></div>
</div>
<?php else : ?>
<h2 class="center">Not Found</h2>
<p class="center">Sorry, but you are looking for something that isn't here.</p>
<?php get_search_form(); ?>
<?php endif; ?>
</div>
<?php get_sidebar(); ?>
<?php get_footer(); ?>

9. You should also check out single.php. This page will be used to show an entry all by itself on a single page, if someone does a search, or is browsing the archives. It is also where people will add comments.

<?php
/**
 * @package WordPress
 * @subpackage Default_Theme
 */

<?php get_header();?>
<div id="quickSummaryfull">
 <p class="p6"><span>&nbsp
 <div class="alignleft"><?php previous_post_link('&laquo; %link') ?></div>
 <div class="alignleft"><?php next_post_link('%link &raquo;') ?></div>
 </span></p>
</div>
<br />
 <div id="content" class="widecolumn" role="main">

 <?php if (have_posts()) : while (have_posts()) : the_post(); ?>

 <div class="navigation">
 <div class="alignleft"><?php previous_post_link('&laquo; %link') ?></div>
 <div class="alignleft"><?php next_post_link('%link &raquo;') ?></div>
 </div>

 <div <?php post_class() ?> id="post-<?php the_ID(); ?>">
 <h2><?php the_title(); ?></h2>

 <div class="entry">
 <?php the_content('<p>Read the rest of this entry &raquo;</p>'); ?>

 <?php wp_link_pages(array('before' => '<p><strong>Pages:</strong> ', 'after' => '</p>',
 'next_or_number' => 'number')); ?>
 <?php the_tags( '<p>Tags: ', ', ', '</p>'); ?>

 <p class="postmetadata alt">
 <small>
 This entry was posted
 <?php /* This is commented, because it requires a little adjusting sometimes.
 You'll need to download this plugin, and follow the instructions:
 http://binarybonsai.com/wordpress/time-since/ */
 /* $entry_datetime = abs(strtotime($post->post_date) - (60*120)); echo time_since($entry_datetime);
 echo ' ago'; */ ?>
 on <?php the_time('l, F jS, Y') ?> at <?php the_time() ?>
 and is filed under <?php the_category(', ') ?>.
 You can follow any responses to this entry through the
<?php post_comments_feed_link('RSS 2.0'); ?> feed.

 <?php if ( comments_open() && pings_open() ) {
 // Both Comments and Pings are open ?>
 You can <a href="#respond">leave a response</a>, or <a href="<?php trackback_url(); ?>"
 rel="trackback">trackback</a> from your own site.

 <?php } elseif ( !comments_open() && pings_open() ) {
 // Only Pings are Open ?>
 Responses are currently closed, but you can <a href="<?php trackback_url(); ?> "
 rel="trackback">trackback</a> from your own site.

 <?php } elseif ( comments_open() && !pings_open() ) {
 // Comments are open, Pings are not ?>
 You can skip to the end and leave a response. Pinging is currently not allowed.

 <?php } elseif ( !comments_open() && !pings_open() ) {
 // Neither Comments, nor Pings are open ?>
 Both comments and pings are currently closed.

 <?php } edit_post_link('Edit this entry','','.'); ?>
 </small>
 </p>
 </div>
 </div>
 <?php comments_template(); ?>
 <?php endwhile; else: ?>
 <p>Sorry, no posts matched your criteria.</p>
<?php endif; ?>
 </div>
<?php get_footer(); ?>

10. Go ahead and check out your changes, http://localhost/wordpress/. You might have to tweak the layout or the main.css file, especially if any of your custom CSS names match the names in WordPress. Remember that CSS is a last-come, last-serve language – whichever declaration is read last will be the one that counts. I had you order you’re CSS file after the WordPress ones for just this reason, anything in your CSS file will overwrite the settings in WordPress. If you’d like, you can merge the two files and clean up any re-declarations. In the long run it’ll be easier to manage, but in the short run it’ll be a pain to sort out all the correct pieces. I’ll show you a short cut on how to do this in another post.

11. Once it looks right, you should make a new thumbnail picture for it. Open the site in a web-browser, take a picture (Cmd-Shift-4), open it in Preview, and resize it (Tools->Adjust Size) to no larger than 300 wide and 225 tall. You should also give your theme a name & author (that’s you). Open style.css and edit Theme Name, Description, and Author. In the Theme URI, put your web address (ex. http://andyhoffner.com), and Version should just be 1.0.

12. Now its time to get it running on your web server. The easiest way is to install a clean WordPress instance, following their “5 Minute Install” all over again. Then, copy your customized “default” template to the server, and just rename it to something unique. This way, you can keep the default template on file for emergency cleanups, or just simple reference.

13. To switch to and activate your new template, log into WordPress (htttp://yourremotewebserveraddress.com/wp-login.php), Click Appearance from the menu on the left, and you should see your new theme, with name and custom thumbnail. Click Activate.

14. You’re done! Congratulations!

Keep checking in for Part 3 of the series!

-Andy

(Re)Building A Blog-based Website From (Near) Scratch – Part 1.5

Wednesday, September 2nd, 2009

Before I dive into Part 2, I thought I might take a step back and sort of give some context to this series. If I was a better writer, I probably would have done this back in Part 1. But I’m not, so I didn’t.

Anyways, the (Re)Building A Blog-based Website From (Near) Scratch title is more descriptive than you might have assumed. Unless you thought it was far too descriptive, in which case you assumed too much. Please refrain from making such assumptions going forward. But for those of us that didn’t jump the gun, let me tell you what it means exactly.

I could have just called this series “Building a Blog-Based Website From Scratch.” This title is far more straightforward. The plan was to write articles under this moniker as I actually designed the site, so that by the time the site was completed, I’d also have some wonderful things to post about.

However, as I actually began to develop the site, and began writing the accompanying articles – the title became less and less, well… true. It wasn’t so much a lie – but more like one of those murky ‘half-truths’. From a pessimistic perspective, you might even call it simply ‘half-false,’ mainly just the “From Scratch” part, which became less and less accurate as I began to salvage, adopt, and mutilate existing frameworks, CSS layouts, etc. – that now make up this very site. See, for something to be “from scratch”, it has to actually be made up of base components. One would assume, for example, that made “from scratch” apple pie would be made from apples, cinnamon, flour, sugar, butter, and… I don’t really know what else… love? Regardless, one would not assume that it was made from pre-sliced-canned apple product and pre-packaged-partially hydroginized-kroger-style-crust preformed disks. Even if you managed to sprinkle love into the latter recipe I am still quite certain it doesn’t qualify as “from scratch.”

Anyways, my point here is that I am going to present to you how to make a website the practical way. “From scratch” is fine for some folks, but I say why reinvent the wheel – if there is a framework or trick to getting the same/similar/or even better results with half the effort – then you’d be crazy not to use it.

While a lot of this stuff isn’t completely “from scratch”, like a pie made from pre-prepared products, you still need to know how to assemble the pieces and bake it all into a warm, gooey slice of website. You following me?

Oh, and the “Re” part of the title is simply indicative that this website is being rebuilt from it’s original content base. I’ll be writing how to best convert/import/organize data from other sources, such as .Mac and non-database-driven blog posts.

Tune in for Part 2 of the series in a couple of days!

-Andy

(Re)Building A Blog-based Website From (Near) Scratch – Part 1

Monday, August 24th, 2009

Part 1: We Start With The Head

When I first started testing layouts for the website – I saw a common theme to most sites. Basically, they would have a static header image, with a fixed size. It didn’t matter if you had a browser window 2000 pixels wide or 20, they usually just centered or justified the image. I wanted my site to be much more dynamic, to feel customized to users on tiny iPhone or a massive HDTV. This meant that the body would be about 80% of the screen width, no matter what the width was.

This meant the header image needed to also be scalable. I couldn’t just dump in a single image, it wouldn’t scale up (or down). So I decided the best thing was to make on with a distant left and right side, and just a centered span with a gradient and my name. This way, items would “stick” to their side, and scale with the window, but it would always appear the correct proportion.

To accomplish this, I would need to separate the header into three basic (and obvious) sections: left, right, center span. I used Photoshop to draft images for each of these elements. I then used 4 divs with the images as the background (left, right, center gradient, center logo text). If you load a page with these divs, they default to being on their own line.

You can eliminate the line breaks by adding “style=’display:inline;’” to the div elements, but that still just puts them one next to another. I needed to layer these divs, which means I need to manually adjust positioning. Absolute wasn’t an option, since I wanted the width to be a function of the containing element, not of the window at large. My first idea was to simply nest them. This works – the layers will stack up nicely – BUT the transparency channel won’t render properly. Since there were ‘partially transparent’ pieces in the headers, like the edges of the leaves, they were dependent on the dark grey background for color. When they were right up against the dark background, it properly bled through to the leaves. If it was layered on top of another transparent images, it didn’t bleed through to the dark background. The images looked lighter and pixellated when stacked in nested divs.

So nesting transparent divs isn’t an option. They would have to be placed on the same level to get the right bleed-through effect with the dark background. The trick was relative positioning. Since each image’s height is fixed, I could just use negative coordinates to move the images up on top of one another.

This let me snap the widths to the containing element and keep them on the same level in the HTML, but place them perfectly on top of one another. The result is rather crude, but effective, as you can see in the header above.

-Andy