Ennui Design http://ennuidesign.com Web designer Jason Lengstorf talks about design, productivity, technology, and anything else that happens to be on his mind. en-us The JavaScript Switcharoo <img src="http://ennuidesign.com/img/userPics/1230411377_87920.jpg" alt="Swapping Input Content with JavaScript" /><br />I hate form labels.<br /> <br /> There. I said it.<br /> <br /> I'm opposed to the idea of forcing a little snippet of text to line up next to each form element so that we know what's going on with it. It's difficult, it takes up extra space, and it tends to make something like a newsletter input eat up too much screen real estate.<br /> <br /> However, it would be rude of me to just assume that everyone knows what the hell I'm asking for when I slap a couple inputs in the top right of a site.<br /> <br /> To get around this issue, I wrote a quick JavaScript function to make label-less forms a possibility without losing that easy-to-identify quality that labels provide.<br /> <br /> <span class="demolink"> <a href="testing/form_test.html">View the Demo</a> </span><br /> <br /> <span class="subhead"> Create the Inputs </span><br /> <br /> Our first step is to create a quick HTML form.<br /> <br /> <span class="code">&lt;form action="processpage.php" method="post" id="form_test"&gt;<br /> &nbsp;&nbsp;&lt;input type="text" value="Name" /&gt;<br /> &nbsp;&nbsp;&lt;input type="text" value="Email" /&gt;<br /> &nbsp;&nbsp;&lt;input type="submit" value="Join the Newsletter!" /&gt;<br /> &lt;/form&gt;</span><br /> <br /> To avoid using labels, I've included a description of the input <em>inside</em> each input. However, in doing so, I've created an inconvenience for the user: they now have to delete the text in the input in order to enter information. This is a definite usability issue, and we need to correct it.<br /> <br /> That's where our JavaScript comes in:<br /> <br /> <span class="code">function formtext(input,initval) {<br /> &nbsp;&nbsp;if (input.value == initval) {<br /> &nbsp;&nbsp;&nbsp;&nbsp;input.value = "";<br /> &nbsp;&nbsp;&nbsp;&nbsp;input.style.color = "#000";<br /> &nbsp;&nbsp;}<br /> }</span><br /> <br /> This function requires two parameters: the input we're dealing with (input), and the label surrogate of said input (initval). It then checks to see if the value of the input matches the initial value, and if so, changes the value to blank and sets the color (which was previously a light grey) to black.<br /> <br /> This allows us to avoid labels and still provide information about the form we're presenting without creating additional steps for our users to complete.<br /> <br /> <span class="subhead"> Worst-Case Scenarios </span><br /> <br /> What if a user selects the field, then clicks away? Should the field remain blank?<br /> <br /> We can avoid blank inputs by writing a second function to check for a blank form.<br /> <br /> <span class="code">function formout(input,initval) {<br /> <br /> &nbsp;&nbsp;if ( input.value == '' || input.value == initval ) {<br /> &nbsp;&nbsp;&nbsp;&nbsp;input.style.color = "#AAA";<br /> &nbsp;&nbsp;&nbsp;&nbsp;input.value = initval;<br /> &nbsp;&nbsp;}<br /> }</span></pre><br /> <br /> If our input is blank, or if somehow the initial value was entered into the field, we'll set the field to its initial value and change the color back to a light grey, thus avoiding a blank input.<br /> <br /> <span class="subhead"> Abstraction, Anyone? </span><br /> <br /> In order to keep our code clean and easy to use, we're going to add an abstraction layer of JavaScript, rather than slapping it inline with our HTML. This is accomplished by placing the two functions above into a file called 'form.js' and inserting the following code along with it:<br /> <br /> <span class="code">if( document.forms ) {<br /> &nbsp;&nbsp;inputs = document.forms[0].getElementsByTagName("input");<br /> <br /> &nbsp;&nbsp;nameInput = inputs[0];<br /> &nbsp;&nbsp;nameInput.onfocus = function() { formtext(this,"Name"); }<br /> &nbsp;&nbsp;nameInput.onblur = function() { formout(this,"Name"); }<br /> <br /> &nbsp;&nbsp;emailInput = inputs[1];<br /> <br /> &nbsp;&nbsp;emailInput.onfocus = function() { formtext(this,"Email"); }<br /> &nbsp;&nbsp;emailInput.onblur = function() { formout(this,"Email"); }<br /> }</span><br /> <br /> This code checks to make sure there is a form, then grabs the first form in your HTML and applies our two functions to the inputs to coincide with events. In this case, we'll run <tt>formtext()</tt> when a user focuses on our input, and <tt>formout()</tt> when they click or tab away from the input.<br /> <br /> And that's really all there is to it! This is a great way to get away from the clutter of form labels without losing usability, and since we've used an abstraction layer, it will degrade gracefully for users that don't have JavaScript enabled.<br /> <br /> <span class="demolink"> <a href="testing/form_test.html">View the Demo</a> </span><br /><br />(To read and post comments for this entry, visit <a href="http://ennuidesign.com/blog/The+JavaScript+Switcharoo">ennuidesign.com</a>)<hr /> http://ennuidesign.com/blog/The+JavaScript+Switcharoo http://ennuidesign.com/blog/The+JavaScript+Switcharoo What I've Learned <img src="http://ennuidesign.com/img/userPics/1228121739_18292.jpg" alt="Learning to Fly" /><br />First and foremost, the Discovery Channel runs <a href="http://www.youtube.com/watch?v=GkZottYDpEE">some crazy shit</a> after dark.<br /> <br /> --<br /> <br /> As an early Christmas gift to myself, I stopped in at Best Buy today and ordered a <a href="http://www.wacom.com/cintiq/12WX.cfm">Cintiq 12WX</a>. It should be here on Friday, and I'm giddy. I've been drooling over this thing <a href="http://twitter.com/jasonatennui/status/876628560">since August</a>, and I can<em>not</em> wait to take it for a test drive.<br /> <br /> --<br /> <br /> Ford managed to impress me with their new ad campaign for the Ford F150.<br /> <br /> <object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/xljekX8TCTY&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/xljekX8TCTY&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object><br /> <br /> I always enjoy video with a heavy emphasis on typography, and it's nice to see a mainstream ad featuring wordplay.<br /> <br /> --<br /> <br /> The <a href="http://www.w3.org/TR/CSS2/generate.html#counters">count()</a> feature in CSS is frustrating unless you get a handle on its scope (which is <em>extremely</em> limited). Pretty much, if you don't have everything you're counting in the same container, you're out of luck and you'll need to use an alternative method of numbering.<br /> <br /> --<br /> <br /> PDF format is a pain in the ass if you don't want browsers to try and open the file inside the browser instead of downloading it. The trick is to set a header to handle PDFs as <tt>application/octet-stream</tt> instead of the default <tt>application/pdf</tt>. If you're able to use .htaccess files on your server, the easiest way to do this is to include the following code inside:<br /> <br /> <tt>&lt;Files *.pdf><br /> ForceType application/octet-stream<br /> Header set Content-Disposition attachment<br /> Header set Content-Transfer-Encoding binary<br /> &lt;/Files></tt><br /> <br /> --<br /> <br /> My father, left unattended, is susceptible to bouts of mad scientist-ism. Recent evidence includes his experiments with a miniature bio-mass furnace.<br /> <br /> I arrived home for Thanksgiving to find him, covered in ash and looking disheveled, holding tin-snips and a charred, soup-can-looking hunk of metal, yelling something about <a href="http://en.wikipedia.org/wiki/Off-the-grid">going off the grid</a>.<br /> <br /> I was invited to help him solve some engineering issues with his "burn can" design (it turns out my design for a self-stirring burn doesn't work).<br /><br />(To read and post comments for this entry, visit <a href="http://ennuidesign.com/blog/What+I%27ve+Learned">ennuidesign.com</a>)<hr /> http://ennuidesign.com/blog/What+I%27ve+Learned http://ennuidesign.com/blog/What+I%27ve+Learned New Site Launch: Lou Schuler <img src="http://ennuidesign.com/img/userPics/1227296468_93630.jpg" alt="This is NOT implying that Lou is full of hot air." /><br />Lou Schuler is kind of a big deal.<br /> <br /> He's written, among others, <a href="http://www.amazon.com/gp/product/1583332944?ie=UTF8&&tag=louschulercom-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=1583332944"><em>The New Rules of Lifting for Women</em></a>, <a href="http://www.amazon.com/exec/obidos/tg/detail/-/1583332383/qid=1129320610/sr=1-8/ref=sr_1_8?v=glance&s=books"><em>The New Rules of Lifting</em></a>, and <a href="http://www.amazon.com/exec/obidos/ASIN/1579547699/louschulercom-20?creative=125577&camp=2321&link_code=as1"><em>The Book of Muscle</em></a>.<br /> <br /> Currently, he's the editorial director of <em>Testosterone</em> (<a href="http://t-nation.com">www.t-nation.com</a>) and the former fitness editor of <em>Men's Health</em> (<a href="http://menshealth.com">www.menshealth.com</a>). In his career he's won multiple awards, including several <a href="http://www.wpa-online.org/">Maggie Awards</a> and the National Magazine Award.<br /> <br /> I'm flattered to be the guy he asked to bring his website up-to-date, and even more excited to get this site in the public eye.<br /> <br /> This site marked a new phase in my web design: I've been learning all sorts of new things that make sites run just a little cleaner, code read a little easier, and my life just a tad better.<br /> <br /> Check <a href="portfolio/Lou+Schuler/">my portfolio</a> for some technical details.<br /><br />(To read and post comments for this entry, visit <a href="http://ennuidesign.com/blog/New+Site+Launch%3A+Lou+Schuler">ennuidesign.com</a>)<hr /> http://ennuidesign.com/blog/New+Site+Launch%3A+Lou+Schuler http://ennuidesign.com/blog/New+Site+Launch%3A+Lou+Schuler Are You Making Any Sense? <img src="http://ennuidesign.com/img/userPics/1224652390_46739.jpg" alt="Capsaicin!" /><br /><em>"Rewind what you just said there, and look at it through the eyes of a non-geek."</em><br /> <br /> My friend said this to me in jest when I got way too excited about the wine project over on <a href="http://okaydave.com">OkayDave.com</a>, but it got me thinking: does anybody know what the hell I'm talking about when I get going on a topic?<br /> <br /> My main interest is my clients, and making sure that they understand what I'm talking about; it doesn't do much good for anyone if I'm just babbling in Geekanese and the client is nodding with a blank stare.<br /> <br /> Additionally, and far worse, is the disconnect between developers and end-users (see?! JARGON!) when turning over the reins of an application. What seems natural to a power-geek may feel awkward and foreign to the average user, and we, as developers, are responsible for putting ourselves in the shoes of the user.<br /> <br /> To keep myself from completely befuddling my clients, I devised a rule of thumb to guide both my conversations and applications:</p><h3>Would my mom get this?</h3><p class="entrytext">Ever versatile, my mother has become one of my most valuable development resources. When I'm getting close to done with an app, I'll call my mom and ask if she's near a computer. If she has the time, I direct her to the beta location of the project and turn her loose without any hints or instructions. If she can't figure out what to do, I know I need to reevaluate how my app presents itself.<br /> <br /> Similarly, in conversation, I try to think like I'm talking to my mom. That keeps my tone conversational, rather than instructive, and encourages me to steer away from phrases such as "server-side versus client-side implementation."<br /> <br /> Communication is key. How do you make sure you're conveying your ideas clearly?<br /><br />(To read and post comments for this entry, visit <a href="http://ennuidesign.com/blog/Are+You+Making+Any+Sense%3F">ennuidesign.com</a>)<hr /> http://ennuidesign.com/blog/Are+You+Making+Any+Sense%3F http://ennuidesign.com/blog/Are+You+Making+Any+Sense%3F New Site Launch: Built For Show <img src="http://ennuidesign.com/img/userPics/1222323412_56108.jpg" alt="Send it to the stars..." /><br />After a few all-nighters, I'm happy to announce the launch of <a href="http://builtforshow.com">www.BuiltForShow.com</a>!<br /> <br /> <em>Built For Show</em> is a book set to hit shelves in late November, written by my long time friend and not-so-long-time client, <a href="http://thenategreenexperience.com">Nate Green</a>. It's aimed at 18 to 35 year old men interested in becoming more attractive to the fairer sex.<br /> <br /> The website is a fairly straightforward effort; we opted to avoid bells and whistles in favor of driving traffic to Nate's parent site, <a href="http://thenategreenexperience.com">www.TheNateGreenExperience.com</a>, which features his blog and acts as his home base on the Internet.<br /> <br /> Also launched today is a revamp of The Nate Green Experience blog, as well as a light redesign of the site's sidebar.<br /> <br /> A more in-depth summary of BuiltForShow.com will be posted in my portfolio tomorrow, as well as an update to TheNateGreenExperience.com's entry.<br /> <br /> Let me know what you think in the comments!<br /><br />(To read and post comments for this entry, visit <a href="http://ennuidesign.com/blog/New+Site+Launch%3A+Built+For+Show">ennuidesign.com</a>)<hr /> http://ennuidesign.com/blog/New+Site+Launch%3A+Built+For+Show http://ennuidesign.com/blog/New+Site+Launch%3A+Built+For+Show Reading RSS with PHP <img src="http://ennuidesign.com/img/userPics/1222054787_72213.jpg" alt="Use only the pieces of the Flickr RSS feed that you want." /><br /><font size="3"><strong>The Problem</strong></font><br /> The Internet seems to be getting easier everyday. With sites like Myspace, Flickr, YouTube, and Twitter, you can essentially create a full-on interactive web experience for free and with no knowledge of web design. This is great, but it limits your creativity, and it also requires your readers to remember multiple separate URLs.<br /> <br /> On the flipside, you <em>could</em> reverse engineer all of these tools and create your own versions of them for use on your personal website, creating the same immersive user experience you get from using social tools, but that's a good deal of time and effort. The learning experience of building such tools is great, but we don't always have hundreds of hours to dedicate to rebuilding Flickr's robust photo management. Besides, doesn't it seem a little silly to reinvent the wheel?<br /> <br /> So, what we're hoping for is a way to get the best of both worlds: how can we utilize the power of Flickr on our own website without needing to dedicate a great deal of time to solving the problem?<br /> <br /> <font size="3"><strong>The Solution</strong></font><br /> One solution is to use RSS feeds to grab the content off of our various social media sites (in this example, we'll use Flickr). This way, we don't have to create any content at all. We simply need to grab the content from our account, figure out how to read it right into our website, and then display it in such a way that it will mesh with the rest of our site's design.<br /> <br /> In this tutorial, we'll build a PHP class to load and parse a Flickr RSS feed, isolate the pieces of information we need, and output formatted XHTML to the browser. When we're done, it should look like this <a href="testing/flickrtest.php">demo Flickr module</a>.<br /> <br /> <font size="3"><strong>Necessary Tools and Skills</strong></font><br /> I'm assuming for the purposes of this tutorial that you have a Flickr account, a basic understanding of PHP 5, and a good grasp on XHTML and CSS. You'll also need a server that supports PHP 5.<br /> <br /> <font size="3"><strong>Collect the Pieces</strong></font><br /> Our first step is to find the RSS feed for our Flickr page. The feed is located at the bottom of the main photostream, and it looks like this:<br /> <br /> <img src="img/flickr_tut-feedloc.png" alt="RSS Feed Location on a User Profile" class="imgdisp" /><br /> <br /> You'll more than likely want to use the "Latest" option. After you click it, you'll get your browsers default RSS feed display, probably offering options to subscribe using a number of services. This is not what we're worried about, though. We want the URL of this page, which should look something like this:<br /> <br /> <span class="code">http://api.flickr.com/services/feeds/photos_public.gne?id=22352410@N07&amp;lang=en-us&format=rss_200</span><br /> <br /> In a moment we'll use this URL to load our Flickr page into our website. But first, we need to tell our site how to handle this information.<br /> <br /> <font size="3"><strong>Creating the Class</strong></font><br /> We start by creating a file named <span class="code">flickr.php</span> and declaring the class flickr to contain all of our code:<br /> <br /> <span class="code">&lt;?php<br /> &nbsp;&nbsp;class flickr {<br /> <br /> &nbsp;&nbsp;}<br /> ?></span><br /> <br /> Now that we have our class, we need to declare all of the variables we're going to need. Because this is a pretty simple class, we only need one:<br /> <br /> <span class="code">&nbsp;&nbsp;var $feed;</span><br /> <br /> The variable <span class="code">$feed</span> will hold the URL of the Flickr page we're loading.<br /> <br /> Next, we'll create a constructor for the class. This is the function that runs when the class is first instantiated. We'll use that to assign the feed URL to the class instance to allow our code to load the proper feed. <br /> <br /> <span class="code">&nbsp;&nbsp;function flickr($feed) {<br /> &nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;feed = $feed;<br /> &nbsp;&nbsp;}</span><br /> <br /> Now we have a class that has the address of our Flickr feed. Pretty simple so far, right?<br /> <br /> <font size="3"><strong>Getting Our Information from the Feed</strong></font><br /> Here's where it starts getting a little tricky. Now we need to load that URL and parse it to extract the relevant information. To do this, we'll create a new function, <span class="code">parse</span>:<br /> <br /> <span class="code">&nbsp;&nbsp;function parse() {<br /> &nbsp;&nbsp;&nbsp;&nbsp;$rss = simplexml_load_file($this-&gt;feed);<br /> &nbsp;&nbsp;&nbsp;&nbsp;$photodisp = array();<br /> &nbsp;&nbsp;&nbsp;&nbsp;foreach ($rss-&gt;channel-&gt;item as $item) {<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$link&nbsp;&nbsp; = (string) $item-&gt;link; // Link to this photo<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$title = (string) $item-&gt;title; // Title of this photo<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$media&nbsp;&nbsp;= $item-&gt;children('http://search.yahoo.com/mrss/');<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$thumb&nbsp;&nbsp;= $media-&gt;thumbnail-&gt;attributes();<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$url&nbsp;&nbsp;&nbsp;&nbsp;= (string) $thumb['url']; // URL of the thumbnail<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$width&nbsp;&nbsp;= (string) $thumb['width']; // Width of the thumbnail<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$height = (string) $thumb['height']; // Height of the thumbnail<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$photodisp[] = &lt;&lt;&lt;________________EOD<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class="flickr_photo"&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a href="{$link}"&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;img src="{$url}"<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;width="{$width}"<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;height="{$height}"<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;title="{$title}"<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alt="{$title}"<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;style="border:0;" /&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/a&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;<br /> ________________EOD;<br /> &nbsp;&nbsp;&nbsp;&nbsp;}<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;return $photodisp;<br /> &nbsp;&nbsp;}</span><br /> <br /> In order to pull down the information from this feed, we'll take advantage of the SimpleXML extension that was introduced in the release of PHP 5. To read more in-depth about this useful tool, there is a great <a href="http://devzone.zend.com/node/view/id/688">article about SimpleXML</a> on the Zend network.<br /> <br /> In line 02, we load the feed from Flickr using the SimpleXML extension and place it in the variable <span class="code">$rss</span>. This allows us to then extract data from the feed.<br /> <br /> Line 03 creates the variable <span class="code">$photodisp</span>, which is an array to hold each photo as we pull it out of the database.<br /> <br /> In line 04, we start a <span class="code">foreach</span> loop to break the feed into individual photos for processing.<br /> <br /> Lines 05-11 load pieces of information from the feed into variable for use as we see fit. For the purposes of this class, we grab the URL for the photo's display page, the name of the photo, the location of the thumbnail image, and the thumbnail's width and height.<br /> <br /> (<em>Note:</em> lines 07 and 08 load variables that we don't use for display; this is because the Flickr feed uses <a href="http://en.wikipedia.org/wiki/XML_namespace">XML namespaces</a>. These are a useful, albeit confusing, XML convention that helps prevent ambiguity of separate elements for easier reading. Our code is accessing the namespace contained in <span class="code">http://search.yahoo.com/mrss/</span> and identifying the thumbnail's URL, width, and height.)<br /> <br /> Finally, in lines 14-26, we use the <a href="http://us.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc">heredoc syntax</a> to produce a formatted string of HTML that not only works well with CSS, but also looks great as source code (one of my pet peeves is hard-to-read source HTML)!<br /> <br /> Each photo is stored in the array <span class="code">$photodisp</span> for use in our next step: formatting for output.<br /> <br /> <font size="3"><strong>Format Your Photos for Output</strong></font><br /> Now that we have all of the photos stored in an array, we set up a new function to create a web-ready block of HTML for displaying all of your photos.<br /> <br /> <span class="code">&nbsp;&nbsp;function display($numrows=6,$head="Photos on Flickr") {<br /> &nbsp;&nbsp;&nbsp;&nbsp;$photodisp = $this-&gt;parse();<br /> &nbsp;&nbsp;&nbsp;&nbsp;$i = 0;<br /> &nbsp;&nbsp;&nbsp;&nbsp;$thumbs = &lt;&lt;&lt;____________EOD<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--// FlickrFeedr by Ennui Design<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; www.EnnuiDesign.com | answers@ennuidesign.com //--&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class="ennui_widget_head"&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{$head}<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class="ennui_widget"&gt;<br /> ____________EOD;<br /> &nbsp;&nbsp;&nbsp;&nbsp;while ( $i &lt; $numrows ) {<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$thumbs .= $photodisp[$i];<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$i++;<br /> &nbsp;&nbsp;&nbsp;&nbsp;}<br /> &nbsp;&nbsp;&nbsp;&nbsp;$trim = str_replace('http://api.flickr.com/services/feeds/photos_public.gne?id=', '',$this-&gt;feed);<br /> &nbsp;&nbsp;&nbsp;&nbsp;$user = str_replace('&amp;lang=en-us&amp;format=rss_200','',$trim);<br /> &nbsp;&nbsp;&nbsp;&nbsp;$thumbs .= &lt;&lt;&lt;____________EOD<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class="ennui_widget_footer"&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;span&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a href="http://www.flickr.com/photos/{$user}/"<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;title="http://www.flickr.com/photos/{$user}/"&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;View All Photos on Flickr<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/a&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/span&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--// End FlickrFeedr by Ennui Design //--&gt;<br /> ____________EOD;<br /> &nbsp;&nbsp;&nbsp;&nbsp;return $thumbs;<br /> &nbsp;&nbsp;}</span><br /> <br /> Let's break that down. First, we'll be passing the variable <span class="code">$numrows</span> when we call this function. This is how many photos we're going to display on the site. The default value is 6, which works well in 1, 2, and 3 column displays, making it a safe bet.<br /> <br /> Then in line 02, we run the <span class="code">parse</span> function we just created. This loads the array into the variable we'll call <span class="code">$photodisp</span> for ease of use. Line 03 sets the variable <span class="code">$i</span> to zero. We'll use this for a <span class="code">while</span> loop to build our content.<br /> <br /> Lines 04-10 start our output (using the heredoc syntax again). We're building the header of our display, as well as starting the div that will contain the photos.<br /> <br /> The meat of this function happens in lines 11-14. Here, we are essentially telling the function, "while the number of photos we've grabbed is less than the number we're allowed to display, grab the next photo from the array." And, since we already formatted the output in the parse function, we don't have to do anything else with it!<br /> <br /> In lines 17 and 18, we take the feed URL and trim out just the user name (in my Flickr feed, this user name is "22352410@N07"). This way, we can use it to send a site visitor to your Flickr photostream's homepage, eliminating any further data input or reliance on a visitor's memory of an additional URL.<br /> <br /> Lines 19-27 finish up the HTML for the display, and then line 29 returns our output.<br /> <br /> That's it! Now all we have to do is call the class and let 'er rip!<br /> <br /> Implementing the Class<br /> Our last step is to place the code on our homepage that will call this class and produce our new Flickr display!<br /> <br /> <span class="code">&lt;?php<br /> &nbsp;&nbsp;include('_class/flickr.php');<br /> &nbsp;&nbsp;$flickr = new flickr('http://api.flickr.com/services/feeds/photos_public.gne?id=22352410@N07&amp;lang=en-us&format=rss_200');<br /> &nbsp;&nbsp;echo $flickr->display(8,"Ennui on Flickr");<br /> ?></span><br /> <br /> <font size="3"><strong>Wrap-Up</strong></font><br /> We have now successfully created a PHP class that loads, parses, and displays a Flickr user's photostream feed! With a little CSS styling and proper placement, you can now seamlessly integrate your Flickr stream into your own website.<br /> <br /> Below, you can download the complete files used to create the <a href="testing/flickrtest.php">fully functional Flickr RSS parsing demo</a>.<br /> <br /> <a href="http://ennuidesign.com/tutorial/flickr.zip" title="Download the files for this tutorial">Download the files for this tutorial</a> (ZIP Archive, 2KB)<br /> <br /> Enjoy! Please leave any questions and suggestions in the comments, as well as links to your site with the Flickr RSS parser in place!<br /><br />(To read and post comments for this entry, visit <a href="http://ennuidesign.com/blog/Reading+RSS+with+PHP">ennuidesign.com</a>)<hr /> http://ennuidesign.com/blog/Reading+RSS+with+PHP http://ennuidesign.com/blog/Reading+RSS+with+PHP Sleep Better at Night <img src="http://ennuidesign.com/img/userPics/1222064748_12163.jpg" alt="Combat insomnia with some simple arithmetic" /><br />I am a light sleeper. I wake up to the sound of my cell phone vibrating, to the sound of a car door closing, to the sound of my downstairs neighbor smoking a cigarette and talking on his cell phone beneath my window. While this is annoying, especially because I live in an old building with paper-thin walls, it's never really been a problem for me because I can generally fall asleep quickly.<br /> <br /> Lately, however, I've been having a really hard time falling asleep, and I wasn't sure why until last night, when I was staring at my ceiling, listening to the wind blowing my bedroom door against the door frame softly, I realized something: <em>I <strong>cannot</strong> sleep when I'm stressed.</strong></em><br /> <br /> Now, let's all take a moment to appreciate the <em>Duh!</em> factor of that statement. You done? Okay, now pay attention.<br /> <br /> I know that stress is a major contributor to insomnia, and that there are probably hundreds of articles and blogs written about it, but that's not what I'm worried about. What worries me is that I went sleepless for almost two weeks before I even <em>realized</em> that I was even stressed in the first place.<br /> <br /> I have a theory, and among my friends it's been holding pretty true: <em>you can reduce your stress enormously by simply <strong>naming the factors in your life that are stressing you out</strong></em>.<br /> <br /> I'm relatively convinced that stress comes not from having too many deadlines or from the hectic nature of our lives, but rather from the feeling of dread that springs from feeling that things in our lives are out of control and that we have no idea what's going on. It's that feeling of losing control that is freaking us out, <strong>not the workload, personal problems, or lack of time</strong>.<br /> <br /> For example, right now I'm stressed out because I'm working a pretty steady forty to forty-five hours a week at a day job, working on four freelance projects, interviewing with a few companies for a higher-paying, more fulfilling day job, and trying to start a band, all while attempting to keep my personal life (i.e. getting to the gym, cooking meals, cleaning my apartment, grocery shopping, etc.) in some kind of flow. That's a lot of balls to keep in the air, and I've never been great at multi-tasking. So I've felt really stressed; I worry that I don't have enough free time to keep up with my freelance projects, but I'm scared that I can't afford to lose my day job until I have more freelance work; I'm terrified that I'm going to to end up half-assing my new musical endeavors because I'm "too busy" to put effort into it; I haven't been grocery shopping in two and a half weeks, and I missed a couple workouts, so I've been feeling like I'm gaining weight and falling back to my old, bad nutritional habits.<br /> <br /> My last couple weeks have been permeated with that gut-wrenching feeling of being late for work, and I barely noticed it because I was making myself so frantic. I lost sleep, which left me feeling groggy and actually detracted from my productivity, resulting in <em>more</em> panic and, therefore, less sleep.<br /> <br /> <strong>So how do we break the cycle?</strong><br /> <br /> For starters, I had to sit down and list everything that I had going on. If you look above, it looks like a lot, but when I list it, it gets pretty simple:<br /> <br /> <strong>1. Full-Time Day Job</strong> (40-45hrs weekly)<br /> <strong>2. Freelance Work</strong> (10-20hrs weekly)<br /> <strong>3. Band Practice</strong> (2-4hrs weekly)<br /> <strong>4. Job-Hunting</strong> (<1hr weekly)<br /> <strong>5. Cooking, Cleaning, Working Out, etc.</strong> (7-8hrs weekly)<br /> <br /> So, I'm looking at needing about 78 hours a week, at most, to accomplish everything I feel I need to accomplish. If I'm sleeping 8 hours a night, that means that in the average week I have 112 hours of productive time (168 hours a week - 56 hours of sleep a week = 112 waking hours). That means that I have <strong>34 hours a week to burn</strong> before I even start wasting the time I need to keep up with my life. Add in a couple dinners with friends and a movie, and I've still got <em>an entire day</em> to waste, all while getting a full night's sleep.<br /> <br /> Knowing that you've got the time won't make you any better at time management, and it certainly won't take care of your responsibilities for you, but the fact of the matter is, there's plenty of time in the week. And just realizing that you're not spread as thin as you may have thought could be just the comforting thought to help you drift off to sleep easily.<br /> <br /> Have you had similar experiences? How do you keep yourself sane with a heavy load of responsibility? Let me know in the comments!<br /><br />(To read and post comments for this entry, visit <a href="http://ennuidesign.com/blog/Sleep+Better+at+Night">ennuidesign.com</a>)<hr /> http://ennuidesign.com/blog/Sleep+Better+at+Night http://ennuidesign.com/blog/Sleep+Better+at+Night You Should Sweat the Small Stuff <img src="http://ennuidesign.com/img/userPics/1222064709_20766.jpg" alt="Don't let something like dirty dishes derail your productivity." /><br />I work two jobs: I work as a freelance web designer and software programmer in the evenings and on weekends, and to make sure I'm making ends meet, I keep a second full-time job, which I don't hate, but I don't particularly enjoy, either.<br /> <br /> As you can imagine, the hours have a tendency to run long, and I find weeks slipping away without so much as a single memory outside of work, the gym, and my apartment. And when I had a live-in girlfriend, my time was even more thinly spread, which left me going to sleep every night an hour or two later than I'd wanted to and waking up feeling like I'd spent my whole <a href="http://en.wikipedia.org/wiki/Rapid_eye_movement_sleep">REM cycle</a> in a dead sprint.<br /> <br /> Something had to change, but I didn't really know how to fix it. I thought my options were to quit the freelance work, which I really enjoy and which pays well (when I have a contract), or to quit the day job, which I don't really want, but which would mean I might not be able to make rent and still afford other things I need, such as, you know . . . food.<br /> <br /> I felt stuck.<br /> <br /> But then I found the secret, and started taking my time back. You know what I did to save my sanity? I started doing the dishes.<br /> <br /> Sounds crazy, right?<br /> <br /> My epiphany was this: <em>I'm not really that short on time.</em> Rather, I'm prone to let a couple dozen three-minute projects ball up into that <a href="http://www.youtube.com/watch?v=vOdpU7j6I44">boulder that chases Indiana Jones</a>. I'll come home from my day job and think about how I need to clean my apartment, do the dishes, write an email, do laundry, check the mail, and any number of other menial tasks that I need to accomplish.<br /> <br /> Then, instead of ignoring them and working, I just sit down and <a href="http://www.youtube.com/watch?v=4JMOh-cul6M">spiral out of control on YouTube</a> until it's time to go to bed, and by then I've not only stressed myself out because I didn't get any freelance work done, but also because I didn't get any of those menial tasks that were originally stressing me out done, either.<br /> <br /> The worst part about it is that I timed myself cleaning my apartment, checking the mail, cooking dinner, and doing my dishes. It took me an hour. Total. As in, to do <strong>all of it.</strong><br /> <br /> Things that take longer, things like grocery shopping, preparing meals for the week, or doing laundry, I found, can be grouped into one four-hour block on a Sunday.<br /> <br /> Once I realized that, I had a good, hard look in the mirror and said to myself, <strong><em>"Where the fuck does all my time go?!"</em></strong><br /> <br /> And then I made the decision to fix it. So now, I come home from my day job or the gym, put on some music, and then I do the dishes, straighten my apartment, and take care of any bills, mail, email, or other obligations that could otherwise stress me out if not dealt with. This process, when done regularly, will only consume about twenty minutes immediately after I get home, allowing me to then concentrate on things that are really important, even if all that means is being able to really, truly <em>relax</em> for once.<br /> <br /> I had this epiphany about a month or two ago, and since then I've actually found the time to be bored. I've slept in, I've spent time doing nothing with friends - I even found the time to watch the entire first season of <a href="http://www.nbc.com/Heroes/about/">Heroes</a>.<br /> <br /> I've also successfully doubled my freelance income, and I'm receiving leads on new clients at nearly three times the rate I was six months ago. Most of that comes from my increased productivity, now that I can sit down and <em>work</em> instead of just clicking around my computer and wishing my projects would somehow code themselves.<br /> <br /> So, yeah; sweat the small stuff. Get it the hell out of your way so you can do the shit that's <em>really</em> important, like <a href="http://youtube.com/watch?v=nTrAtqaDuMA">beating up on children.</a><br /> <br /> <strong><em>How do you keep your free time free?<br /> <br /> Let me know in the comments!</em></strong><br /> <br /> <em>This blog originally ran on March 21st, 2008, when I guest posted on <a href="http://thenategreenexperience.com/?id=1&blog=60&page=4">Nate Green's blog</a>.</em><br /><br />(To read and post comments for this entry, visit <a href="http://ennuidesign.com/blog/You+Should+Sweat+the+Small+Stuff">ennuidesign.com</a>)<hr /> http://ennuidesign.com/blog/You+Should+Sweat+the+Small+Stuff http://ennuidesign.com/blog/You+Should+Sweat+the+Small+Stuff