<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">

    <title type="text">C77 Studios / Mark J. Reeves</title>
    <subtitle type="text">C77 Studios / Mark J. Reeves:</subtitle>
    <link rel="alternate" type="text/html" href="http://c77studios.com/index/" />
    <link rel="self" type="application/atom+xml" href="http://www.c77studios.com/site/atom/" />
    <updated>2008-08-26T20:27:33Z</updated>
    <rights>Copyright (c) 2007, Mark</rights>
    <generator uri="http://www.pmachine.com/" version="1.5.2">ExpressionEngine</generator>
    <id>tag:c77studios.com,2007:11:15</id>


    <entry>
      <title>Almost there, Safari</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/almost_there_safari/" />
      <id>tag:c77studios.com,2007:index/1.35</id>
      <published>2007-11-15T16:18:00Z</published>
      <updated>2007-11-15T19:26:42Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <category term="Technology"
        scheme="http://www.c77studios.com/"
        label="Technology" />
      <category term="Web Development"
        scheme="http://www.c77studios.com/"
        label="Web Development" />
      <content type="html"><![CDATA[
        <p>I want to use <a href="http://www.apple.com/safari" title="Safari">Safari</a> as my regular browser. <a href="http://gigaom.com/2007/11/13/webkit/" title="WebKit">WebKit</a>&#8216;s taking off. There&#8217;s solid development efforts going on. It&#8217;s native to my OS. It&#8217;s never been quite there, though.
</p>
<p>
I&#8217;m a Firefox fan and advocate generally. One of the reasons for my support is its support for plugins, including the <a href="http://chrispederick.com/work/web-developer/" title="Web Developer Toolbar">Web Developer Toolbar</a>, which I use daily. When developing and testing pages, I frequently disable the browser cache so my refresh is ensured to contain the latest changes. This makes browsing any other site near impossible. Every little star icon in Gmail has to load every time the Inbox is refreshed.
</p>
<p>
Fully functional Gmail support is important to me. For that reason, I&#8217;d been using Firefox&#8217;s cousin, <a href="http://caminobrowser.org/" title="Camino">Camino</a>, for Gmail, regular browsing, and project management web apps. Something&#8217;s been a little off there too, though.
</p>
<p>
So I tried Safari again recently, with the 3.0 beta. I ran into a few snags, though, that really impact me:
</p>
<ol><li><strong>In Gmail, I could not hit tab from the Message field to hit the Send button.</strong> After composing a message using nothing but the keyboard&#8212;even to enter a recipient&#8217;s address and have Gmail autocomplete it for me&#8212;I had to reach for the mouse to send.</li>
<li><strong>In <a href="http://www.backpackit.com" title="Backpack">Backpack</a> To Do lists, the cursor wouldn&#8217;t place in the next, new list item automatically.</strong> Again, entering content with the keyboard, hitting enter on a To Do item submitted it, and left the cursor...nowhere. Reach for the mouse to click into the autogenerated new field.</li>
<li><strong>Using Gmail Notifier as my default client, Safari&#8217;s &#8220;Mail Link to this Page&#8221; menu item wouldn&#8217;t launch a compose screen.</strong> In the past I&#8217;ve seen errors saying Gmail Notifier wasn&#8217;t supported. Recently it would launch a browser window but would redirect to the Inbox instead of the compose screen. At that point I switched my default browser back to Firefox, which did successfully launch the compose window when I mailed a link from Safari.</li></ol>
<p>
They sound small, but they&#8217;re things I do all day long. I gave up. Decided to use Firefox full-time. That left me with my management apps (email, project management, etc) in the same application as my development windows. Not good, either.
</p>
<p>
Then I read the Surfin&#8217; Safari post, &#8221;<a href="http://webkit.org/blog/122/webkit-3-10-new-things/" title="Ten New Things in WebKit 3">Ten New Things in WebKit 3</a>,&#8221; this morning. After my first pass through, I wanted to comment and say, &#8220;Yes, but until these three things work for me, I cannot switch to take advantage of these 10 new things!&#8221; I couldn&#8217;t comment. I couldn&#8217;t find an email address to comment.
</p>
<p>
I read through the article again and saw this:
<br />
<blockquote><p>WebKit 3 fixes many bugs, and supports additional text editing features like links and lists. We now have support from web applications like WordPress, Google Docs, GMail, Blogger, and many more.</p></blockquote>
<p>
I downloaded the OS X Tiger 10.4.11 update, launched Safari, browsed to Gmail, and&#8230;
</p>
<p>
We&#8217;re good. I can tab to the Send button. I can launch a compose screen. I can add To Do items with just the keyboard in Backpack. Now, however, typing in the To field in Gmail isn&#8217;t providing me the autocomplete address lookup! I&#8217;ve been noticing a severe lag in this in all browsers lately, and suspect something on Google&#8217;s end. This needs to be working and working fast. I need to be able to hit Compose (or hit &#8216;C&#8217; on the keyboard), be in that field, type a name, and be on my way to composing.
</p>
<p>
Once that&#8217;s there, I&#8217;ll be happy, and using Safari full time.
</p>
<p>
If you find yourself bouncing back and forth between browsers to try out features or for different uses, <a href="http://www.sheepsystems.com/products/bookdog/" title="Bookdog">Bookdog</a> is a great little OS X app for migrating and synchronizing bookmarks.
</p>
<p>
<strong>Update:</strong> I just noticed an &#8220;Older Version&#8221; link in Gmail. I clicked that and found myself in a Gmail where autocomplete of addresses in the To field works in Safari. I again wasn&#8217;t able to tab to the Send button, though. In fact, tabbing from the Message field brought me to the Subject field and inserted tab characters. So it&#8217;s up to Gmail to restore autocomplete...?
</p>
<p>
<strong>Update 2:</strong> It&#8217;s becoming apparent that once I type an address into the &#8220;New Version&#8221; of Gmail, it&#8217;s available in autocomplete going forward. I&#8217;ve also noticed that every Gmail screen now has &#8220;?ui=2&#8221; in the URL. Things could be working out nicely in Safari 3.
</p> 
      ]]></content>
    </entry>

    <entry>
      <title>Who&#8217;s writing about office chairs?</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/whos_writing_about_office_chairs/" />
      <id>tag:c77studios.com,2007:index/1.34</id>
      <published>2007-10-30T23:07:00Z</published>
      <updated>2007-10-31T16:32:42Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <content type="html"><![CDATA[
        <p>I&#8217;m moving into an office November 1st. I&#8217;ve got an IKEA desk at home to bring in. I&#8217;ve got the <a href="http://www.apple.com/mac" title="computers">computers</a> already. I&#8217;ve got a set of chrome shelves, some computer speakers, and a <a href="http://www.ikea.com/us/en/catalog/products/70033870" title="few spare chairs">few spare chairs</a> for seating. I need to buy an <a href="http://www.apple.com/airportexpress/" title="Airport Express">Airport Express</a> for wi-fi. I need to buy a good desk chair.
</p>
<p>
With two days to go, I&#8217;m no closer than I was two weeks ago. I&#8217;m not up for the drive to IKEA, or the shipping charges and blind faith required for an online purchase. I checked Staples: prices were low, but nothing grabbed me, and I&#8217;ve encountered too many online reviews that they fall apart after a few months of use.
</p>
<p>
I consider it a worthwhile investment, but I can&#8217;t afford an <a href="http://hermanmiller.com/CDA/SSA/Product/1,1592,a10-c440-p8,00.html" title="Aeron">Aeron</a> chair or a <a href="http://store.steelcase.com/articles.asp?id=155" title="Steelcase Think">Steelcase Think</a>, much as I&#8217;d like one. I swore earlier I was going to buy a Herman Miller <a href="http://hermanmiller.com/CDA/SSA/Product/1,1592,a10-c440-p217,00.html" title="Celle">Celle</a> for <a href="http://www.officedesigns.com/product-exec/product_id/345/pn/Basic%20Celle%20Chair" title="$450">$450</a>, until I saw that adjustable arms and adjustable lumbar jacked the price up to $630.
</p>
<p>
I ordered an <a href="http://www.sit4less.com/products/office-star/office-star-2300-executive-black/121" title="Office Star 2300 for $249">Office Star 2300 for $249</a>, with free shipping. It had all the adjustable features I was looking for. I waited a day to find out just how soon I&#8217;d get it, and was told it was backordered til December. That explains why it&#8217;s out of stock on Staples&#8217; site ($259). It was a gamble anyway.
</p>
<p>
I&#8217;m intrigued by the lineup at <a href="http://www.sitonit.net/home/product-category.asp?category=task" title="SitOnIt Seating">SitOnIt Seating</a>, including the affordable <a href="http://www.sitonit.net/home/product-overview.asp?product=tr2&amp;category=task&amp;shortName=Task" title="TR2">TR2</a>, but the few sites I find it for sale on offer myriad configuration options, making it difficult to figure out what exactly you are choosing and getting. And unlike the Aeron or Think, the Internet isn&#8217;t abuzz with positive opinions. Or epinions. Or countless other sites that don&#8217;t actually offer reviews but really just product descriptions and links to retailers.
</p>
<p>
<strong>Update:</strong> <em><a href="http://furniture.about.com/od/homeoffice/ss/officechairs_5.htm" title="This ranking">This ranking</a> puts the TR2 in the top 10. I found one retailer with a Yahoo! store and <a href="http://www.chairsnow.com/tr2-40.html" title="priced one at $370">priced one at $370</a> with the adjustment options I wanted. I&#8217;ve got a request to SitOnIt to inquire about ordering direct. I also came across an article citing a KI rep, who said paying anything more than $250 was paying for looks, so I&#8217;ve got a request in with them to inquire about their <a href="http://www.ki.com/product/product_model.asp?app=16&amp;pl=195&amp;model=438" title="Impress">Impress</a> chair.</em>
</p>
<p>
Who&#8217;s writing about their experiences with these chairs? Who&#8217;s pointing to solid, reliable, comfortable mid-range products? Chairs that don&#8217;t cost $500-1000 for comfort and reliability. <a href="http://www.jasonsantamaria.com/archive/2007/07/20/have_a_seat.php" title="Jason Santa Maria">Jason Santa Maria</a> asked for recommendations, and ended up with a <a href="http://www.humanscale.com/products/freedom_index.cfm" title="Humanscale Freedom">Humanscale Freedom</a> off Craigslist. <a href="http://boston.craigslist.org" title="My Craigslist">My Craigslist</a> searches haven&#8217;t proven so fruitful.
</p>
<p>
Can anyone recommend a site with recommendations on office chairs? (Or a non-office superstore in the area&#8212;Boston or the North Shore&#8212;to check some of these options out?)
</p>
<p>
<strong>Update:</strong> <em>Just found <a href="http://paulstamatiou.com/2007/06/13/review-herman-miller-celle-chair/" title="this review of the Celle">this review of the Celle</a> that was informative. Still $630 with options.</em>
</p> 
      ]]></content>
    </entry>

    <entry>
      <title>A mishmash of recent updates</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/a_mishmash_of_recent_updates/" />
      <id>tag:c77studios.com,2007:index/1.33</id>
      <published>2007-10-12T04:27:00Z</published>
      <updated>2007-10-16T04:21:45Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <category term="Clients"
        scheme="http://www.c77studios.com/"
        label="Clients" />
      <category term="Mobile"
        scheme="http://www.c77studios.com/"
        label="Mobile" />
      <category term="News"
        scheme="http://www.c77studios.com/"
        label="News" />
      <category term="Personal"
        scheme="http://www.c77studios.com/"
        label="Personal" />
      <category term="Web Development"
        scheme="http://www.c77studios.com/"
        label="Web Development" />
      <content type="html"><![CDATA[
        <h5>Busy</h5>
<p>
Last month I took on a full-time on-site contract gig in addition to a handful of projects. The contract ended 10/5, and I&#8217;m down to just one of the other projects, in addition to October&#8217;s workload. I&#8217;m very much booked for the next few months and continuing to receive requests. To keep up with all of this, I&#8217;m looking at a few options, including finding some allies to delegate production work to, and now looking for office space, so I can be more productive than I am in my corner of our home.
</p>
<h5>My iPhone</h5>
<p>
My iPhone has become indispensable. There&#8217;s been a few quirks and idiosyncrasies over the past month, but when I was heading into Boston on the train daily, and sitting on a desktop computer as a contractor, having the iPhone handy for email, the web, and music was awesome. That said:
</p>
<ul><li><strong>Battery life:</strong> It hasn&#8217;t let me down yet, but I&#8217;ve had red 20% and 10% warnings on the train on the way home. Of course I&#8217;d spend much of the day refreshing email, and using Safari on EDGE on the train. Internet usage is the biggest drain. I guess 10.5 hours of usage isn&#8217;t so bad with that in mind.</li>
<li><strong>Mail:</strong> I&#8217;ve had one frustration with mail and it&#8217;s largely stemmed from one client with images embedded in their mail signature. I&#8217;d already been routing all my POP addresses through one Gmail account, so I just set up Gmail through the iPhone&#8217;s predefined settings. The only catch is with attachments. A download, even if the two-line preview is displayed, is forced when there&#8217;s an attachment to an email. Is this always true? Not sure. Do I have to sit and watch it say &#8220;Loading...&#8221; every time I&#8217;ve gone back to one of their emails. Yup.</li>
<li><strong>Fast EDGE and slow EDGE:</strong> I read somewhere on the web that there are actually two versions of the EDGE network in use. I could tell you which one I was on at a given moment while on the train. EDGE is not particularly fast, but it&#8217;s functional. Slow EDGE is slow and cumbersome. Waiting 1 minute for an email to load is no good.</li>
<li><strong>Crashed</strong> There were a few incidents, especially after the latest update (1.1.1). Sometimes I&#8217;d hit a page in Safari and the music would just stop. When I went back into iPod, it wouldn&#8217;t remember what album I was in, but would revert to a previous selection. One morning it completely locked. I had to look up how to reset it (hold both buttons in til it does), to reboot it and regain control. Another morning, as I slid the slider to unlock it, it stuck at the right edge. Hitting the top button would show/hide the splash screen, with the slider halfway up the screen. I had to reboot it then too.</li></ul>
<p>
I have not hacked it. I bought an iPhone to be productive with it and to use what Apple provided, not compromise that. (Interesting thoughts on that <a href="http://diveintomark.org/archives/2007/10/04/if-wishes-were-iphones">here</a>. And the other side of the story, sort of, <a href="http://www.tuaw.com/2007/10/03/tuaw-interview-ambrosias-andrew-welch-on-the-iphone-update-and/">here</a>.) At home, on wifi, it&#8217;s amazing. I can grab it and sit on the couch and have a full Internet experience in my hand. The only thing I&#8217;ve played with was renaming MP3s to create ringtones in iTunes, which 1.1.1 broke.
</p>
<p>
Btw, WordPress is <a href="http://shawnblanc.net/2007/wordpress-iphone-admin-plugin/">optimized for iPhone</a>.
</p>
<h5>Transparent PNGs</h5>
<p>
I&#8217;ve been trying to shift production work to using PNGs for some time. With two recent projects I&#8217;ve finally taken the time to make it work, not without some snags.
</p>
<p>
The process I&#8217;ve been using:
</p>
<ol><li>Save for Web in Photoshop (CS2) as PNG-24 if you want alpha transparency (anti-aliased - edge colors fading over the background). To do this, you need to cut the graphic over a transparent background. You can also go transparent GIF style, and use PNG-8, which will allow you to select multiple transparent colors, but the edges up to those colors will be aliased. You can&#8217;t float an image over any background with PNG-8; you need to match the background color.</li>
<li>I then grab the images from my iMac over the network to my laptop, where I do coding. I drag and drop them onto <a href="http://www.shealanforshaw.com/introducing-gammaslamma-10-for-osx/">GammaSlamma</a>, a mac product that strips Photoshop&#8217;s embedded color profile info out of the image files. This was my biggest challenge working with PNGs. They&#8217;d render different colors in Safari and Firefox on the Mac, and probably different on Windows. GammaSlamma eliminates that concern.</li>
<li>There&#8217;s still a problem with PNG-24: IE6. It doesn&#8217;t support alpha transparency in PNGs. There&#8217;s a solution. You can find it at <a href="http://www.twinhelix.com/css/iepngfix/">http://www.twinhelix.com/css/iepngfix/</a>. Unfortunately that solution isn&#8217;t without its snags. Because it replaces images through references to their parent, it breaks when you apply it to positioned elements. (You also have to specify each element with a PNG background image that it&#8217;s going to hit, as by default it just grabs all img tags.) Why is this a problem? Well, the project I&#8217;m currently working on has all these nice little boxes with rounded corners that can grow vertically over a gradient background. Using &#8220;bottom left&#8221; for my background image breaks when that image has position and is fixed, and binding a button to the bottom using position: absolute and a position: relative container, not to mention that that button is a PNG-24 background image, breaks too. I got around it by using a double wrapper div, but I&#8217;m not a fan of that. I had to give up on the rounded corners and do PNG-8 and push back on the gradient background. Same for the background-image I was swapping using jQuery in the top of the box as different tabs were clicked. I had to do PNG-8, and it can only sit over a specific background. Still, some progress has been made. A few steps can provide some nice effects, providing the layout is tempered with some restraint so they don&#8217;t pile up too fast.</li></ol>
<h5>Recent work</h5>
<p>
I need to put together a portfolio update together highlighting some recent work I&#8217;ve done. For now I&#8217;ll just say:
</p>
<p>
Cadillac, XSLT, NBC, Playskool, sIFR, jQuery, .NET, <a href="http://www.westchestercountybusiness.com/archive/091707/0917070001.php4">client press coverage</a> (for <a href="http://www.rackandgo.com/">Rack &amp; Go</a>).
</p>
<h5>Color suggestions?</h5>
<p>
I put together this version of C77 so I could update the design purely through CSS. I grabbed a palette (Giant Goldfish) off <a href="http://www.colourlovers.com">COLOURlovers</a> and applied it. I&#8217;m looking for something new. If you&#8217;d like to suggest 5 or 6 colors that would work well, some orange is a must, feel free to send them my way.
<br />

</p> 
      ]]></content>
    </entry>

    <entry>
      <title>Wanted: Freelance XHTML/CSS Developer</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/wanted_freelance_xhtml_css_developer/" />
      <id>tag:c77studios.com,2007:index/1.32</id>
      <published>2007-09-28T03:48:01Z</published>
      <updated>2007-09-28T03:49:50Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <category term="Clients"
        scheme="http://www.c77studios.com/"
        label="Clients" />
      <category term="News"
        scheme="http://www.c77studios.com/"
        label="News" />
      <category term="Personal"
        scheme="http://www.c77studios.com/"
        label="Personal" />
      <category term="Web Development"
        scheme="http://www.c77studios.com/"
        label="Web Development" />
      <content type="html"><![CDATA[
        <p>Posted on Craigslist Boston: 2007-09-27, 10:46PM EDT
</p>
<p>
I&#8217;m a freelance web developer and consultant who partners with designers and agencies (as well as direct client engagements) on projects ranging from backend, data-driven application development to production work based on Photoshop comps. My clients turn to me because I&#8217;m fast, detail-oriented and think through the ins and outs of their projects and designs.
</p>
<p>
I&#8217;m reaching a point where more work is coming my way than I can take on. I&#8217;m not looking to fill a position here, but for someone who&#8217;s got some free time and is looking for opportunities to shine in quick turnaround projects, expand their skillset, and make some extra cash. If you&#8217;re looking for some after-hours work or are a freelancer with some gaps to fill, get in touch.
</p>
<p>
A few requirements (and pluses):
</p>
<p>
* You&#8217;re fast, a fast learner, know your way around Photoshop and CSS, and are savvy enough to dev on a local server and sync your changes with a staging site.
<br />
* You not only &#8220;get&#8221; web standards, but value them, and look for opportunities to deliver optimized, maintainable, accessible and search-friendly markup.
<br />
* You can tell me who the key players are in the web standards/CSS field, and why they&#8217;re important.
<br />
* You can show me that you take pride in your work, through a portfolio or site with your name on it.
<br />
* I&#8217;ll be impressed by the markup I see there.
<br />
+ Experience with jQuery.
<br />
+ Experience with ExpressionEngine.
<br />
+ Knowledge of PHP/MySQL or .NET/SQL Server.
</p>
<p>
How we&#8217;ll work together:
</p>
<p>
I&#8217;ll split my rate with you proportionate to the work I delegate you on a given project. I bill clients hourly and on flat project fees, so it varies from job to job.
</p>
<p>
I have high standards for work that goes out the door and how I work with my clients. I&#8217;m looking for someone willing to follow my lead, and would like to be in a position where I can start a project, doing initial guides and slices in Photoshop and initial page templates, and then hand those off to build out. Integrity is of paramount importance. If that sounds good to you, let&#8217;s talk about working together.
</p>
<p>
More info on rates and my portfolio by email. More about me at c77studios.com
</p> 
      ]]></content>
    </entry>

    <entry>
      <title>I got an iPhone</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/i_got_an_iphone/" />
      <id>tag:c77studios.com,2007:index/1.31</id>
      <published>2007-09-09T04:54:00Z</published>
      <updated>2007-09-09T05:39:00Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <category term="Mobile"
        scheme="http://www.c77studios.com/"
        label="Mobile" />
      <category term="News"
        scheme="http://www.c77studios.com/"
        label="News" />
      <category term="Technology"
        scheme="http://www.c77studios.com/"
        label="Technology" />
      <category term="Web Development"
        scheme="http://www.c77studios.com/"
        label="Web Development" />
      <content type="html"><![CDATA[
        <p>A few weeks back I was in NYC with my designer counterpart. With time to kill after the meeting we took the train down for, and before our train back, we headed up to the Fifth Avenue Apple Store.
</p>
<p>
I hadn&#8217;t touched an iPhone yet. As with the store (an Apple store under a big glass box), I thought it was nice, but I wasn&#8217;t blown away. The iPhone was nice, but not <em>$600</em> nice.
</p>
<p>
As I&#8217;ve posted recently, though, I&#8217;ve become somewhat enamored by the prospects of developing for the iPhone, and after a meeting last Wednesday, I was offered the opportunity to be reimbursed for one to be able to do real-world testing of a project I&#8217;m pretty excited about.
</p>
<p>
I started hitting <a href="http://www.engadget.com" title="Engadget">Engadget</a> on my Sidekick II after the meeting, and saw all the new goodies, and the price drop on the iPhone. Thursday I headed into the Apple Store nearest me (North Shore Mall in Peabody, MA), where none of the new products were out. That was fine: 8gb and 4gb iPhones were $200 off, making my 8gb model $399, as promised. (You can actually get 4gb models for $299 while they last).
</p>
<p>
My intent was to bypass the activation process, documented days after its initial release, and just use it on wifi at home. It didn&#8217;t take long for me to decide to activate it, for the full experience, leaving my T-Mobile account active until my contract&#8217;s up in November.
</p>
<p>
<img src="http://www.c77studios.com/images/uploads/P1020821.jpg" alt="photo" width="350" height="262" />
</p>
<p>
So I&#8217;ve got one. And my verdict? It&#8217;s nice. A few things threw me off at first, but once I got everything set to sync how I wanted, it couldn&#8217;t be better.
</p>
<ul><li><strong>Mail:</strong> I started with all my accounts copied over and quickly turned them all off. I&#8217;m now down to a C77Studios.com account for when I want to send with that address and my Gmail account, which all my other accounts already forward into. I tried doing Gmail with POP first, wasn&#8217;t happy, and then used the built-in Gmail settings. That threw me off too. The Inbox doesn&#8217;t filter based on a cut-off date. It just shows 25, 50, 100, etc of your emails. The key is: &#8220;Use Recent Mode.&#8221; This grabs the latest email and pushes the others down. The 50th email is bumped out to make room for the 1st. You&#8217;re always viewing your most recent, and if you want to make room for more, you can Delete. You can&#8217;t empty your Trash, though, and you can&#8217;t move a message to another folder to keep it handy. That bothers me a bit.</li>
<li><strong>More on Gmail:</strong> I&#8217;ve seen some complaints that whenever you send Gmail, it ends up in your Inbox. This isn&#8217;t an iPhone issue. This is how POP with Gmail has always worked. It&#8217;s because Gmail treats all your mail as one big collection. The Inbox, Archive, and Sent views in the Gmail application are just views; they&#8217;re not distinct folders. It&#8217;s actually handy sometimes to have a sent message in your Inbox anyway.</li>
<li><strong>EDGE:</strong> Slow. Useful for iPhone-optimized sites. Checking email takes a minute.</li>
<li><strong>Mobile Safari:</strong> Awesome. I LOVE that I can have multiple &#8220;windows&#8221; open, which is a habit I&#8217;m used to on the desktop. Accessing <a href="http://www.haveamint.com" title="Mint">Mint</a> using the iPhone Pepper is swell. I use Camino and Firefox on my mac more than Safari, so I&#8217;m working on a process of migrating bookmarks into Safari for syncing using <a href="http://www.sheepsystems.com/products/bookdog/" title="Bookdog">Bookdog</a> and perhaps at some point Automator.</li>
<li><strong>iPhoto:</strong> I took some pictures, set the wallpaper. I synced. Every time I synced my phone, iPhoto opened again asking me to sync. iPhoto sees your phone as a digital camera; you have to treat it as one. Delete all the pics from the iPhone when you import. If you want them back on it, drop them in an album that you set to sync. You just can&#8217;t leave them in Camera Roll.</li>
<li><strong>YouTube:</strong> Phenomenal quality while on wifi. Haven&#8217;t tried it on EDGE.</li>
<li><strong>Google Maps:</strong> Crazy to be holding a pic of my building in my hand. Haven&#8217;t really used it to navigate yet.</li>
<li><strong>Contacts:</strong> This took a while. <a href="http://www.zeldman.com/2007/07/25/what-apple-copied-from-microsoft/" title="Zeldman described this well">Zeldman described this well</a>. The iPhone convinces you to abandon existing habits in favor of syncability. I&#8217;ve got email addresses in Gmail. I&#8217;ve got contacts in <a href="http://www.highrisehq.com" title="Highrise">Highrise</a>. I&#8217;ve got numbers on my old cell phone. I once downloaded all my <a href="http://www.linkedin.com" title="LinkedIn">LinkedIn</a> contacts and imported them into Address Book. When I first synced my iPhone, it was full of people I&#8217;d never even call. I purged Address Book and started clean, manually entering and organizing friends, family and business contacts. I&#8217;m happy now. We&#8217;ll see how keeping up with it goes.</li>
<li><strong>Overall:</strong> It&#8217;s easy to use and despite the lock on features, it feels personal. I&#8217;ve done the <a href="http://www.macrumors.com/iphone/2007/09/07/free-custom-ringtones-in-itunes-7-4/" title="ringtone hack">ringtone hack</a>, and redone it post-7.4.1 update. I&#8217;m not too intent on doing anything else to it yet (Installer hacks, etc). It is <em>difficult</em> to use in the car. I&#8217;m thrilled that I can use the Plantronics 510 Bluetooth headset I bought for my mac in the car now. (My Sidekick II doesn&#8217;t have Bluetooth.) But you can&#8217;t make a call on a non-tactile keypad without looking down. Voice activation?</li>
<li><strong>And the keyboard:</strong> I knew when I first saw it weeks ago I could make it work. I&#8217;m pretty quick and clean typing, but it&#8217;s one-fingered looking down for confirmation. That&#8217;s the drawback. With my Sidekick II flipped open, I could tell where I was on the keys just like on a traditional keyboard and could focus on what I was typing rather than how. It&#8217;s a great UI, but it&#8217;s going to take some getting used to. I&#8217;ll mention the lack of Keychain (or saved passwords) in this context too. Without that, you have to navigate form fields and reenter account info every time you visit a login site. Something to put on the nice-to-have list.</li></ul>
<p>
I&#8217;m still playing with it. I spent the better part of this evening importing music from my iMac into iTunes on my MacBook so I could sync some with the iPhone. I&#8217;m very pleased with it so far. Definitely <em>$399</em> nice.
</p> 
      ]]></content>
    </entry>

    <entry>
      <title>.MOBI: Making Strides</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/mobi_making_strides/" />
      <id>tag:c77studios.com,2007:index/1.30</id>
      <published>2007-09-03T23:42:00Z</published>
      <updated>2007-09-04T18:46:34Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <category term="Mobile"
        scheme="http://www.c77studios.com/"
        label="Mobile" />
      <category term="Technology"
        scheme="http://www.c77studios.com/"
        label="Technology" />
      <category term="Web Development"
        scheme="http://www.c77studios.com/"
        label="Web Development" />
      <content type="html"><![CDATA[
        <p>The Internet&#8217;s really just about lots and lots of information. It happens to be that many of us access that information through web-based or desktop email clients and web pages. In many parts of the world, a mobile handset is a user&#8217;s only gateway to the Internet. No matter how big your screen, the lines are blurring between these disparate interfaces. Email, IM and social network messaging are becoming interchangeable, and web content is all over (think Twitter updates via SMS). We&#8217;re getting closer and closer to the promise of <a href="http://en.wikipedia.org/wiki/Ubiquitous_computing" title="ubiquitous computing">ubiquitous computing</a> (think tricorders on Star Trek).
</p>
<p>
The iPhone&#8217;s launch has brought attention and sophistication to the mobile web. Whether or not you&#8217;re sold on Apple&#8217;s execution, you probably look forward to the enhancements on other devices that it will inspire.
</p>
<p>
My second cell phone was from SprintPCS in 2000. It had a web interface that allowed me to read predefined news selections. I can&#8217;t recall much else about it. I next switched to Voicestream and got a Nokia 3390 Gold, with AOL IM on it. I&#8217;m not sure if I had web access, but I did start text messaging with that phone. From there it was to Cingular to get the new (at the time - in 2004?) Nokia phone that unfolded to expose a full QWERTY keyboard that was split with the screen in the middle. I loved many things about that phone, but the email client was a clunky Java app and the web browser still left much to be desired.
</p>
<p>
Most recently, two years ago, I got a T-Mobile Sidekick II. Easy to use, the Sidekick has a cheezy interface, but offers POP email, AOL IM, SMS, and web browsing. The web browser on the Sidekick does not read mobile stylesheets. Instead it pulls content through <a href="http://danger.com/" title="Danger">Danger</a>&#8216;s server, formatting and positioning things down the narrow page. I use my Sidekick a lot, most often while on commuter trains. All of my email is copied to it, and I use IM when I&#8217;m away from the desk. I use the browser regularly to access sites like <a href="http://news.google.com" title="Google News">Google News</a>, <a href="http://www.huffingtonpost.com" title="the Huffington Post">the Huffington Post</a>, <a href="http://www.google.com/reader/m" title="Google Reader (mobile)">Google Reader (mobile)</a>, and <a href="http://www.digg.com/iphone" title="Digg for the iPhone">Digg for the iPhone</a>. I&#8217;ve yet to encounter a link I can&#8217;t click through and read in full. The only handicap is that I&#8217;ve disabled JavaScript to improve rendering times.
</p>
<p>
Now we have the iPhone with Mobile Safari that renders pages in full and allows you to zoom in and out to read regions of content. Opera Mini, found on Nokia phones and available as a download where Java apps are supported <a href="http://www.operamini.com/beta/simulator/" title="behaves similarly">behaves similarly</a> in its next version. Google leveraged the iPhone&#8217;s launch to be a real mobile player by embedding its Maps and YouTube apps onto the iPhone.
</p>
<p>
Now <a href="http://gigaom.com/2007/09/03/google-phone-facts/" title="Google's about to launch a mobile device">Google&#8217;s about to launch a mobile device</a>.
</p>
<p>
What&#8217;s my point in all this? Critical mass is imminent. You can&#8217;t ignore this stuff anymore. I <a href="http://www.c77studios.com/post/whats_coming_for_the_web/" title="What's Coming for the Web">wrote about this</a> a few months back and <a href="http://www.c77studios.com/post/c77_studios_on_the_iphone/" title="C77 Studios on the iPhone">recently took a pass at formatting my content for the iPhone</a>. While the potential offered by these devices is their improvements at making all web sites accessible on mobile, the real promise is in making content usable on them. Optimization. And to create an optimal experience, you need to understand the experience. I&#8217;ll likely gravitate toward the iPhone, perhaps replacing my Sidekick with one as my T-Mobile contract is up in November, and I&#8217;ve been a bit disappointed with T-Mobile of late. As I incorporate mobile into my practices, I&#8217;ll be sharing what I learn here, beginning with some recent announcements and resources I&#8217;ve been following:
</p>
<ul><li><a href="http://alistapart.com/articles/putyourcontentinmypocket">Put Your Content in My Pocket</a> by Craig Hockenberry at <a href="http://www.alistapart.com">A List Apart</a></li>
<li><a href="http://mobilewebbook.com/">Mobile Web Design</a> was released last week by <a href="http://www.cameronmoll.com">Cameron Moll</a></li>
<li>The <a href="http://www.marketcircle.com/iphoney/">iPhoney</a> emulator which I, sans iPhone, used to develop C77Studios.com/iPhone</li>
<li><a href="http://www.operamini.com/beta/simulator/">Opera Mini Simulator</a> - Opera Mini is a popular mobile browser. The simulator enables you to preview your site as it would appear.</li>
<li>Apple Developer Connect - <a href="http://developer.apple.com/iphone/">Web Development for iPhone</a></li>
<li><a href="http://www.michelf.com/projects/multi-safari/">Multi-Safari</a> - If you&#8217;ve upgraded to Safari Beta 3 for testing iPhone dev, you can run older versions of Safari for your day-to-day testing</li>
<li><em>Added 9/4/2007:</em> <a href="http://www.webstandards.org/2007/08/22/the-good-the-bad-and-the-ugly-iphone-edition/">The good, the bad, and the ugly - iPhone edition</a> on WebStandards.org</ul>
<p>
If you&#8217;ve got any pointers or just want to connect on mobile development, email <a href="mailto:mjr@c77studios.com">mjr@c77studios.com</a>. You can also access my latest posts to del.icio.us and contact info at <a href="http://www.c77studios.com/iphone" title="C77Studios.com/iPhone">C77Studios.com/iPhone</a>.
</p>
<p>
<em>For more posts about mobile web development, visit <a href="http://www.c77studios.com/archives/category/mobile" title="http://www.c77studios.com/archives/category/mobile">http://www.c77studios.com/archives/category/mobile</a>.</em>
</p> 
      ]]></content>
    </entry>

    <entry>
      <title>C77 Studios on the iPhone</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/c77_studios_on_the_iphone/" />
      <id>tag:c77studios.com,2007:index/1.29</id>
      <published>2007-08-28T21:17:00Z</published>
      <updated>2007-09-04T01:27:20Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <category term="Mobile"
        scheme="http://www.c77studios.com/"
        label="Mobile" />
      <category term="News"
        scheme="http://www.c77studios.com/"
        label="News" />
      <category term="Technology"
        scheme="http://www.c77studios.com/"
        label="Technology" />
      <category term="Web Development"
        scheme="http://www.c77studios.com/"
        label="Web Development" />
      <content type="html"><![CDATA[
        <p>I don&#8217;t yet have an iPhone, but <a href="http://alistapart.com/articles/putyourcontentinmypocket" title="Put Your Content in My Pocket">Put Your Content in My Pocket</a> on <a href="http://www.alistapart.com" title="A List Apart">A List Apart</a>, and today&#8217;s release of <a href="http://cameronmoll.com/" title="Cameron Moll">Cameron Moll</a>&#8216;s <a href="http://mobilewebbook.com/" title="Mobile Web Design">Mobile Web Design</a> got me eager to play with structuring a site for one.
</p>
<p>
You can essentially view an iPhone-optimized site in any browser, including Safari and Firefox. To better simulate the experience, I downloaded the <a href="http://www.marketcircle.com/iphoney/" title="iPhoney emulator">iPhoney emulator</a>. Here&#8217;s what things look like in iPhoney:
</p>
<p>
<img class="nostyle" src="http://www.c77studios.com/images/uploads/C77_on_iPhoney.png" alt="photo" width="386" height="728" />
</p>
<p>
The emulator&#8217;s bigger than the device in your hand. It&#8217;s designed that way so the resolution of what&#8217;s rendered matches the higher resolution of the actual iPhone. I find <a href="http://www.digg.com/iphone" title="the Digg iPhone interface">the Digg iPhone interface</a> really appealing, and used that as a basis. What I haven&#8217;t picked apart yet is the nifty JavaScript Digg uses to slide from the list of topics to the actually posts, which are contained in the same page.
</p>
<p>
The page is managed by my ExpressionEngine install, and uses the Magpie plugin I <a href="http://www.c77studios.com/post/ee_aggregating_content_using_magpie_and_expressionengine/" title="previously covered">previously covered</a> to pull in del.icio.us links.
</p>
<p>
There&#8217;s a few steps I took to make the page iPhone-friendly. The following meta tag in your page keeps the iPhone from scaling the page as it typically would. We&#8217;re formatting the page specifically for the iPhone.
</p>
<blockquote class="code"><p>&lt;meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/&gt;</p></blockquote>
<p>
The HTML is a straightforward series of &lt;p&gt; and &lt;a&gt; tags, with the &lt;a&gt; tags set to display: block with dimensions making the entire shape &#8220;clickable&#8221; by a finger of any size.
</p>
<p>
In the CSS, I set the body to turn off scrollbars, even though I did code to the anticipated width:
</p>
<blockquote class="code"><p>body { overflow: hidden; }</p></blockquote>
<p>
Then I defined all my shapes to fit 100% of the screen, so that they fill it nicely when turned sideways or vertical:
</p>
<blockquote class="code"><p>width: 80%; height: 25px; line-height: 25px; padding: 10px 15% 10px 5%; font-size: 15px;</p></blockquote>
<p>
Finally, all the &lt;a&gt; tags have a background image (the right-pointing arrow) positioned as:
</p>
<blockquote class="code"><p>background-position: right center;</p></blockquote>
<p>
That&#8217;s the gist of the coding. And if you&#8217;re really, really into the content that I post to del.icio.us and share on C77, you can now access it from your iPhone. Enjoy!
</p>
<p>
<em>For more posts about mobile web development, visit <a href="http://www.c77studios.com/archives/category/mobile" title="http://www.c77studios.com/archives/category/mobile">http://www.c77studios.com/archives/category/mobile</a>.</em>
</p> 
      ]]></content>
    </entry>

    <entry>
      <title>WEBDEV: Screen Scraping with .NET 2.0</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/webdev_screen_scraping_with_net_20/" />
      <id>tag:c77studios.com,2007:index/1.28</id>
      <published>2007-08-28T13:50:00Z</published>
      <updated>2007-08-28T14:30:14Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <category term="Web Development"
        scheme="http://www.c77studios.com/"
        label="Web Development" />
      <content type="html"><![CDATA[
        <p>For many screen scraping is most associated with legacy systems, green monochrome terminals of data, and is an approach to mine data from the memory — or screen — of an incompatible system and get it somewhere where it’s more readily consumed.
</p>
<p>
The term can also apply to HTML, and web pages, and in this context it often has a nefarious connotation as it can be easily abused. The techniques below would allow you to very easily grab a page off someone’s blog, strip out the posts, and re-display them on your own site. Of course I’m not advocating this, and the advent of RSS, and its popularity amongst bloggers for content distribution, renders all this unnecessary. (See <a href="http://www.c77studios.com/post/ee_aggregating_content_using_magpie_and_expressionengine/">EE: Aggregating content using Magpie and ExpressionEngine</a>.)
</p>
<p>
I worked on a project where it was necessary, though. A client’s antiquated site featured a set of “robots”: CGI scripts that harvested content from industry sites that were aware of the process and approved of its implementation. The scripts were deemed proprietary by the client’s previous vendor and thus had to be rebuilt.
</p>
<p>
The scripts were also cantankerous, and that’s not just a symptom of their age. There’s no parameterization or abstraction in them: when any change to the source web site breaks their functionality they can’t be easily updated.
</p>
<h5>How to build a better bot</h5>
<p>
We can grab the source page from another web site very easily, using the System.Net.WebRequest class and a System.IO.StreamReader.
</p>
<blockquote class="code"><p>WebRequest webrequest = WebRequest.Create(url); // Where url is a string containing the remote URL
</p>
<p>
StreamReader stream = new StreamReader(webrequest.GetResponse().GetResponseStream());
</p>
<p>
System.Text.StringBuilder sb = new System.Text.StringBuilder();
</p>
<p>
string line;
</p>
<p>
while ((line = stream.ReadLine()) != null)
<br />
{ if (line.Length > 0) sb.Append(line); }
</p>
<p>
stream.Close();</p></blockquote>
<p>
That’s it. You’ve now pulled all the HTML from the source page into a string. Note the use of the System.Text.StringBuilder class, with the .Append() method described as 1000 times as fast as string concatenation.
</p>
<p>
That wasn’t enough to actually make use of the content. All I’ve done is grab the source page; I haven’t actually harvested anything from it yet. I also don’t have a fully functional page if I wanted to re-render it in its entirety, as any relative paths to images, stylesheets, etc are now broken.
</p>
<p>
To parameterize identification of blocks of HTML I want to harvest into concise, editable patterns that can be modified to match changes on the other end, I turned to Regular Expressions in C#. Using my url value again, the first thing I did was update all src, href, and @import values to include that URL, <strong>where the existing value did not already start with http://</strong>.
</p>
<blockquote class="code"><p>using System.Text.RegularExpressions;
</p>
<p>
…
</p>
<p>
string output = sb.ToString();
</p>
<p>
output = Regex.Replace(output, “href=\”(?!http)”, “href=\”&#8221; + url);</p></blockquote>
<p>
Repeated for src, and @import values.
</p>
<p>
Now that that’s cleaned up, we can harvest all the headline links from the page, which contained a list of press releases. Using the same Regex call as above to glean the values and store them separately, I set up four patterns:
</p>
<p>
<strong>regex</strong>, to contain the pattern that matches a chunk of HTML for each press release:
</p>
<blockquote class="code"><p>string regex = “(&lt;p class=\”date\”&gt;).*?(&lt;/ul&gt;)”;</p></blockquote>
<p>
<strong>regexLink</strong>, to grab the link from the HTML:
</p>
<blockquote class="code"><p>string regexLink = “(?&lt;=(href=\”)).*?(?=\”)”;</p></blockquote>
<p>
<strong>regexHeadline</strong>, to grab the title of the press release from the HTML:
</p>
<blockquote class="code"><p>string regexHeadline = “(?<=((&lt;a).*?(\"&gt;))).*?(?=&lt;/a&gt;)";</p></blockquote>
<p>
<strong>regexDate</strong>, to grab a date value:
</p>
<blockquote class="code"><p>string regexDate = “(?&lt;=(&lt;p class=\”date\”&gt;)).*?(?=&lt;/p&gt;)”;</p></blockquote>
<p>
In this case, though, we’re using a System.Text.RegularExpressions.MatchCollection to store matches on our chunks of HTML, like so:
</p>
<blockquote class="code"><p>MatchCollection matches = Regex.Matches(output, regex);</p></blockquote>
<p>
We can loop through those matches using the matches.Count value, and then within each match grab our link, headline, and date values using Regex.Match().
</p>
<p>
Unfortunately these are specific to just one page. Each press release on the page starts with a new &lt;p&gt; and ends with the end of a &lt;ul&gt;. I had 45 of these pages that each need a bot. The page I’m tackling here isn’t even consistent: Some items end in a &lt;/a&gt;, some a &lt;br /&gt;, some a &lt;/p&gt;.
</p>
<p>
The nice thing, though, is that each content harvester is defined by four, configurable parameters. Instead of having a file containing functionality for each, I can store them in a database, allow the client to add new ones, clone existing ones, and even set up a process to alert them to changes in the source HTML so that they can update the bot by editing the regex pattern.
</p>
<p>
With a little regex in C#, I was able to prototype all 45 of these and set up the system to maintain them in short order. The only challenge left was to convince the client that they can, and should, learn regex themselves to maintain their own content going forward.
</p>
<p>
<em>While it did not correctly interpret some regex code that C# accommodates, the <a href="http://www.cuneytyilmaz.com/prog/jrx/">JRX/Real-time JavaScript RegExp Evaluator</a> was quite useful. See also the <a href="http://www.regular-expressions.info/reference.html">reference materials</a> at <a href="http://regular-expressions.info/">Regular-Expressions.info</a>.</em>
</p> 
      ]]></content>
    </entry>

    <entry>
      <title>EE: Quick URL redirects using segment variables</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/ee_quick_url_redirects_using_segment_variables/" />
      <id>tag:c77studios.com,2007:index/1.27</id>
      <published>2007-08-22T00:31:00Z</published>
      <updated>2007-09-04T01:30:24Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <category term="Blogging"
        scheme="http://www.c77studios.com/"
        label="Blogging" />
      <category term="ExpressionEngine"
        scheme="http://www.c77studios.com/"
        label="ExpressionEngine" />
      <category term="Web Development"
        scheme="http://www.c77studios.com/"
        label="Web Development" />
      <content type="html"><![CDATA[
        <p><em>This is my second post on using ExpressionEngine to power your blog or web site. ExpressionEngine is a feature-rich content management system used by web designers and developers to power their own and their clients’ web sites. ExpressionEngine works for me as a flexible rendering engine that accommodates custom fields, easy content entry, and a tag-based templating system that anyone can use to store HTML or pre- and post-processed PHP. With ExpressionEngine, I know I’ll never have to say, “sorry, the CMS won’t do that.”</em>
</p>
<p>
<em>This post came about when <a href="http://expressionengine.com/blog/entry/last_week_on_the_forums1/" title="I was linked to on the ExpressionEngine Blog">I was linked to on the ExpressionEngine Blog</a>.</em>
</p>
<p>
Happy as I was when I saw traffic start coming through from <a href="http://expressionengine.com/blog/entry/last_week_on_the_forums1/" title="a link on the ExpressionEngine Blog">a link on the ExpressionEngine Blog</a>, I was dismayed to see that my RSS feed, where the link came from, still had my older entry URL, without the /post. My previous design accommodated multiple entries and single entries on the /index template. ExpressionEngine will serve multiple entries as specified on the &#123;exp:weblog:entries&#125; tag, or filter down to a single entry if it catches its url_title on the URL requested.
</p>
<p>
But single entries weren&#8217;t long enough for the homepage in the new design, and I coded all my single entry links to a /post template. I checked and rechecked my homepage links and archive links, but the RSS feed slipped through the cracks. A single entry link off the homepage made it out into the wild, and I was starting to get some decent traffic on a less-than-perfect page.
</p>
<p>
I shot off an email requesting a change while working on a solution using my old template as a testpad. What did I use? ExpressionEngine&#8217;s segment variable.
</p>
<p>
The segment variable lets you grab a slice of the URL delimited by &#8216;/&#8217;.
</p>
<p>
On the URL
</p>
<blockquote class="code"><p>http://www.c77studios.com/post/ee_aggregating_content_using_magpie_and_expressionengine/</p></blockquote>
<p>
I could output the value &#8216;post&#8217; by saying
</p>
<blockquote class="code"><p>&lt;? echo {segment_1}; ?&gt;</p></blockquote>
<p>
To do so, you need to turn on PHP parsing for the template (Allow PHP?) in the Template Preferences Manager and set the PHP Parsing Stage to Output, so that the PHP code is run on the value output by ExpressionEngine.
</p>
<p>
My first step was to test things by doing a quick &#8216;hello world!&#8217;.
</p>
<blockquote class="code"><p>&lt;?
<br />
if ('{segment_1}' == 'ee_aggregating_content_using_magpie_and_expressionengine')
<br />
{
<br />
echo 'hello world!';
<br />
}
<br />
?&gt;</p></blockquote>
<p>
That worked, so now I had a functional conditional to catch the value. Since this was an urgent fix, I wanted to catch this specific circumstance and get them to the right spot.
</p>
<blockquote class="code"><p>&lt;?
<br />
if ('{segment_1}' == 'ee_aggregating_content_using_magpie_and_expressionengine')
<br />
{
<br />
header('Location: /post/ee_aggregating_content_using_magpie_and_expressionengine/'); exit;
<br />
}
<br />
?&gt;</p></blockquote>
<p>
That accommodated this circumstance and eliminated the issue. NOTE:
</p>
<blockquote class="code"><p>&lt;?
<br />
exit;
<br />
?&gt;</p></blockquote>
<p>
is necessary in an ExpressionEngine template to suppress the rest of the page when redirecting using header(&#8217;Location:url&#8217;);
</p>
<p>
Crisis averted. But what about other URLs out in the wild? How to keep this from happening again, and how to not have single case code sitting around in my template?
</p>
<blockquote class="code"><p>&lt;?
<br />
if (strlen({segment_1}) > 0) {
<br />
header('Location: /post/{segment_1}'); exit;
<br />
}
<br />
?&gt;</p></blockquote>
<p>
There. Now it&#8217;s dynamic. If a request is made 1) on the /index (homepage) template and 2) has a segment variable on it, grab the segment variable and redirect to /post/{segment_1}. Any old URLs out there with the entry-specific url_title directly on the root will bounce to the /post template, right where I want them to be.
</p>
<p>
<em>UPDATE: Unfortunately this method isn&#8217;t foolproof. I had an inbound link with a querystring parameter (c77studios.com?ref=mjr). Even though there&#8217;s no &#8216;/&#8217; on that URL, the link was translated to c77studios.com/?ref=mjr by the browser or server, which created a segment_1 that doesn&#8217;t correspond to a post, which redirected to a dead end. I was able to fix the link, but haven&#8217;t yet updated the code to handle it.</em>
</p>
<p>
<em>For more posts about ExpressionEngine, visit <a href="http://www.c77studios.com/archives/category/expressionengine" title="http://www.c77studios.com/archives/category/expressionengine">http://www.c77studios.com/archives/category/expressionengine</a>.</em>
</p> 
      ]]></content>
    </entry>

    <entry>
      <title>Automate your manual Gantt chart in Excel</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/automate_your_manual_gantt_chart_in_excel/" />
      <id>tag:c77studios.com,2007:index/1.26</id>
      <published>2007-08-16T19:05:00Z</published>
      <updated>2007-08-16T19:59:53Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <category term="Blogging"
        scheme="http://www.c77studios.com/"
        label="Blogging" />
      <category term="Clients"
        scheme="http://www.c77studios.com/"
        label="Clients" />
      <category term="Technology"
        scheme="http://www.c77studios.com/"
        label="Technology" />
      <content type="html"><![CDATA[
        <p>The unstoppable <a href="http://www.davidseah.com">Dave Seah</a> recently <a href="http://davidseah.com/archives/2007/08/13/manual-gantt-charting-in-excel/">posted an Excel file</a> he uses to manually create Gantt charts. It&#8217;s a nice layout, but it&#8217;s manual: You still need to fill in the schedule and apply the cell background colors to define durations on the timeline.
</p>
<p>
About a year ago I put together a spreadsheet in Excel that does a lot of that work for you. I&#8217;d definitely call it a 0.5 version of what it could be. It&#8217;s pretty basic, and relies on some hard-coded values, but it also puts to use Excel&#8217;s date functions to dynamically define durations that skip weekends and holidays, color-code durations by label ("Agency" or &#8220;Client&#8221; in this version), and do all this just by entering a start date and the number of business days to spend on a task.
</p>
<p>
A few things to note:
</p>
<ol><li>This may require one of the Analysis Toolpaks or just a recent version of Excel. I seem to remember adding one of these (Add-Ins under the Tools menu) when I put this together, but my current installation of Excel doesn&#8217;t have any checked. Perhaps I found a workaround.</li>
<li>This is, of course, unsupported. Download it, play with it, improve it, put your logo on it and call it your own. I&#8217;m just sharing some knowledge and a starting point here.</li>
<li>Column A is hidden. In Column A I stored the holidays we were given off where I worked so that, in addition to weekend dates defined by Excel, the chart would know additional days to exclude from the schedule.</li>
<li>The Start Date in Task 1 is a hard-coded value. The End Date is determined by the number of days allocated, and subsequent Start Dates are determined sequentially following that task. This probably isn&#8217;t always the case, but the values can be overridden as you need to.</li>
<li>To use this functionality, do a Fill Down (Ctrl+D) on fields B:G for the number of Tasks you need, editing the Task, Days, and Owner fields for each new row.</li>
<li>Dates across the timeline are linear and the timeline can be expanded by doing a Fill Right (Ctrl+R). The first date should be entered manually.</li>
<li>The duration stripes use conditional formatting. (Conditional Formatting under the Format menu) They&#8217;re in an if...else sequence that first blocks off weekends and holidays in gray, then applies a background color for Agency tasks, and then a background color for Client tasks. It does this based on a formula that checks if the date above is within the range of the task (Start Date/End Date, already calculated or manually entered).</li>
<li>The values that correspond to &#8220;Agency&#8221; and &#8220;Client&#8221; are in the conditional formatting formulas. You can add additional values there.</li>
<li>The conditional formatting grid can be expanded out and down by highlighting cells and doing a Fill Down or Fill Right (Ctrl+D or Ctrl+R).</li></ol>
<p>
That should be enough to get a somewhat savvy Excel user started. This won&#8217;t work magic on its own. It does have enough of the thinking done, though, that it can be expanded and styled to cut down on the number of steps to put together a project schedule.
</p>
<p>
<a href="http://www.c77studios.com/images/uploads/dynagantt.xls">Download dynagantt.xls</a>
</p> 
      ]]></content>
    </entry>

    <entry>
      <title>EE: Aggregating content using Magpie and ExpressionEngine</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/ee_aggregating_content_using_magpie_and_expressionengine/" />
      <id>tag:c77studios.com,2007:index/1.25</id>
      <published>2007-08-16T01:16:00Z</published>
      <updated>2007-09-04T01:30:09Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <category term="Blogging"
        scheme="http://www.c77studios.com/"
        label="Blogging" />
      <category term="ExpressionEngine"
        scheme="http://www.c77studios.com/"
        label="ExpressionEngine" />
      <category term="Web Development"
        scheme="http://www.c77studios.com/"
        label="Web Development" />
      <content type="html"><![CDATA[
        <p><em>This is the first of what will hopefully be a continuing series of posts on using <a href="http://www.expressionengine.com">ExpressionEngine</a> to power your blog or web site. ExpressionEngine is a feature-rich content management system used by web designers and developers to power their own and their clients&#8217; web sites. ExpressionEngine works for me as a flexible rendering engine that accommodates custom fields, easy content entry, and a tag-based templating system that anyone can use to store HTML or pre- and post-processed PHP. With ExpressionEngine, I know I&#8217;ll never have to say, &#8220;sorry, the CMS won&#8217;t do that.&#8221;</em>
</p>
<p>
I recently rearranged and redesigned things here on C77 Studios and one of my goals was to pull in external content server-side. I&#8217;d been using JSON code to pull in my <a href="http://del.icio.us/circa1977">del.icio.us</a> links, which was frustrating me as the JavaScript call to the remote URL would sometimes stall the loading of the full page.
</p>
<p>
<a href="http://magpierss.sourceforge.net/">Magpie</a> is a PHP RSS parser and caching mechanism that pulls RSS feeds from a remote URL and provides an API to grab content and include it in your page output. What&#8217;s even better is <a href="http://expressionengine.com/downloads/details/magpie_rss_atom_parser/">the Magpie ExpressionEngine plugin</a> that was available by default in my install.
</p>
<p>
The plugin does the same thing that the PHP Magpie parser does: it provides an API to grab and parse RSS feeds as well as cache them on the server using a timeout parameter. The caching mechanism is useful. Not only does it queue content for fast page rendering if the remote URL happens to be offline, it also prevents bombarding the URL and getting denied. I saw this happen when I reduced the timeout value and found my del.icio.us feed unavailable for a while.
</p>
<p>
The tag-based syntax for the Magpie ExpressionEngine plugin is really simple:
</p>
<blockquote class="code"><p>&#123;exp:magpie url="http://feeds.feedburner.com/ModernHomesNewEngland" limit="4" refresh="60"&#125;
<br />
{items}&lt;p&gt;&lt;a href="{magpie:link}"&gt;{title}&lt;/a&gt;&lt;/p&gt;{/items}&#123;/exp:magpie&#125;</p></blockquote>
<p>
Really simple: Open and close the exp:magpie tag with a feed URL, limit (number of items to show), and a refresh value for the cache (in minutes). For the items pulled, grab bits from each, in this case the title and link for each post.
</p>
<p>
The example here, that appears in the footer of the page, is from <a href="http://www.modernhomesengland.com">ModernHomesNewEngland</a>, another blog I maintain, so this lets me pull all my blogs together in one portal. I&#8217;ve also, as I mentioned, pulled in the latest 12 items from my del.icio.us bookmarks (on the right side of the page), allowing my del.icio.us account to server double-duty: the portable bookmarking tool it&#8217;s intended to be, and a tool for me to post quick links to my blog. Finally, I&#8217;m using the Magpie plugin to pull my latest <a href="http://www.twitter.com">Twitter</a> post in as a caption in the photo, capturing a quick thought that I can post anytime, anywhere using my cell phone.
</p>
<p>
If you maintain a personal blog or homepage, and contribute to other blogs, or wish to pull your del.icio.us posts in as content for your blog, Magpie on PHP is a powerful tool to grab them server-side rather than having a user&#8217;s browser do all that work in JavaScript. From a content perspective, this is the ultimate goal: Turn your homepage into a publication with lots of good content and resources. Web 2.0 and the API Web have us posting bits and bites (and bytes) all over the place, <em>and it&#8217;s all good content</em>. Magpie helps us easily aggregate all that in one central spot and ExpressionEngine&#8217;s tag-based plugin makes it even easier.
</p>
<p>
<em>For more posts about ExpressionEngine, visit <a href="http://www.c77studios.com/archives/category/expressionengine" title="http://www.c77studios.com/archives/category/expressionengine">http://www.c77studios.com/archives/category/expressionengine</a>.</em>
</p> 
      ]]></content>
    </entry>

    <entry>
      <title>Network Solutions has lost my business</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/network_solutions_has_lost_my_business/" />
      <id>tag:c77studios.com,2007:index/1.23</id>
      <published>2007-07-29T17:07:00Z</published>
      <updated>2007-07-31T05:36:20Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <content type="html"><![CDATA[
        <p>I&#8217;ve been a Network Solutions customer since 1998. I sort of take pride in the fact that my username is a 5-digit number, starting with 16. That among the millions of people who have since acquired domain names, I was among the first 16000. I&#8217;ve paid $35 per domain, per year since then, owning up to 15 domains at a given time. Sometimes I&#8217;ve paid less if I&#8217;ve renewed for multiple years. There&#8217;s been a bit of peace of mind with Network Solutions that a GoDaddy can&#8217;t provide.
</p>
<p>
In May 2007 I let a domain name lapse that I had acquired one year earlier. I wasn&#8217;t using it. I&#8217;ve a renewed interest in securing it, though, and now 2 months after it expired, I&#8217;m told its status is Taken. When I do a WHOIS query on the domain, I see it&#8217;s not owned by anyone; it&#8217;s registered to Network Solutions, and pending delete:
</p>
<blockquote><p>Registrar: NETWORK SOLUTIONS, LLC.
<br />
Whois Server: whois.networksolutions.com
<br />
Referral URL: <a href="http://www.networksolutions.com">http://www.networksolutions.com</a>
<br />
Name Server: NS1.PENDINGRENEWALDELETION.COM
<br />
Name Server: NS2.PENDINGRENEWALDELETION.COM
<br />
Status: pendingDelete</p></blockquote>
<p>
I log into my Gold VIP account and contact support. &#8220;What&#8217;s up here?&#8221; I ask. I let this domain name lapse and it&#8217;s unavailable for me to renew and unavailable for me to purchase. How do we straighten this out and let me renew this?
</p>
<p>
I receive the following:
</p>
<blockquote><p>According to our records, the domain name registration is in a Redemption period status. This means that the domain name registration has been deleted from our database and is in the process of being returned to the market where it will be available for registration by anyone.
</p>
<p>
During the redemption period we can attempt to recover this domain name registration for you.&nbsp; (There is a $150.00 charge for this service.)  If you would like us to do that for you, please contact Customer Service at 1-888-642-9675 to provide your credit card information. If you are calling from outside the U.S. or Canada, please call 1-570-708-8788.&nbsp; As a Network Solutions customer, you are entitled to unlimited access, day or night, to technically skilled customer service representatives who are dedicated to delivering any level of support you may need.
</p>
<p>
Once the domain name registration has been recovered, it will be re-activated in your original account.&nbsp; Allow 3-5 business days for this process to be competed.&nbsp; We hope this information has been helpful. </p></blockquote>
<p>
<strong>$150 to recover a domain name that cost $35.</strong> No mention of how long it will continue to be in the purgatory they call &#8220;the process of being returned to the market where it will be available for registration by anyone.&#8221;
</p>
<p>
Give me a break. That process is called blackmail. Network Solutions is profiting by turning what might be a clerical error, letting ownership lapse without renewing, into a method of squeezing more money out of customers. At least domain squatting, or acquiring valid domain names to set up advertising-rife search portals, is an independent money grab. This is just a way of screwing over customers.
</p>
<p>
With each domain that comes up for renewal in my account, Network Solutions will lose another piece of my business.
</p> 
      ]]></content>
    </entry>

    <entry>
      <title>WEBDEV: Scalable, CSS&#45;based page design</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/webdev_scalable_css_based_page_design/" />
      <id>tag:c77studios.com,2007:index/1.21</id>
      <published>2007-07-10T14:29:00Z</published>
      <updated>2007-08-15T03:33:45Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <content type="html"><![CDATA[
        <p>I wish I could credit the actual source of the tip to make em-based font sizes in CSS more usable. I&#8217;m not quite sure which it is or where the bookmark is.
</p>
<p>
Without looking up and citing an official definition, I&#8217;ll do my best to explain the premise and application: Using em as a unit of measurement in CSS, as opposed to px (pixel) or pt (point) or % (percent), renders the element&#8217;s dimensions or font-size as a multiple of its parent. Thus if the parent&#8217;s font-size was 12px and we style an H2 within as 2em, it will be 24px in size.
</p>
<p>
The tip is to style your body element to have a font-size of 62.5%. Based on browser defaults, this sets the baseline font-size to 10px. Any multiple is now x 10, easy to code. 12px text is 1.2em.
</p>
<p>
This also works for dimensions on elements. We can code a div 100px x 800px as height: 10em, width: 80em. By coding dimensions as a multiple of the baseline font-size, if the user chooses to increase or decrease their browser&#8217;s font-size, the percentage-based font-size on the body element increases/decreases proportionately, as do all our subsequent multiples. This can be applied to every element on the page* to allow the user to scale the entire design using the Ctrl+/Ctrl- (Cmd on the mac, Ctrl/Cmd+0 to return to default) keys on their keyboard. This is a feature supported in most modern browsers.
</p>
<p>
Take a look and see it applied: <a href="http://templates.c77studios.com/new-mjr.html">http://templates.c77studios.com/new-mjr.html</a>
</p>
<p>
The container divs, borders, and fonts all scale as you resize the browser&#8217;s font size, scaling not just the text within the page, but the entire page proportionately.
</p>
<p>
I also played a bit with transparent PNGs in the page, placing some of the tree branches in the foreground, over the content, and some in the background. You&#8217;ll see that positions and dimensions of those images can also be defined with em measurements, so that they not only scale in size as the browser font is resized, but also in relative position, giving you the effect of zooming in closer or out further.
</p>
<p>
* I have encountered some instances in IE where decimal em values, such as 81.1em, don&#8217;t always render as an exact translation to a px value, in this case 811px. IE also seems to round, while other browsers will seem to render, smaller values, such as 1.25em. If planning on using these techniques, though, this should be avoidable by designing to even-value dimensions before coding.
</p> 
      ]]></content>
    </entry>

    <entry>
      <title>WEBDEV: Build an option list using SQL</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/webdev_build_an_option_list_using_sql/" />
      <id>tag:c77studios.com,2007:index/1.20</id>
      <published>2007-07-09T18:29:00Z</published>
      <updated>2007-08-16T02:03:19Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <content type="html"><![CDATA[
        <p>After <a href="http://www.c77studios.com/webdev_convert_an_option_list_to_sql_with_textmate_and_regular_expressions/" title="converting another site's option list to SQL to insert the values into my database">converting another site&#8217;s option list to SQL to insert the values into my database</a>, I want to get those values back out into an option list with IDs.
</p>
<p>
I started with:
</p>
<blockquote class="code"><p>&lt;option value=&quot;Acura&quot; &gt;Acura&lt;/option&gt;
<br />
&lt;option value=&quot;Alfa Romeo&quot; &gt;Alfa Romeo&lt;/option&gt;
<br />
&lt;option value=&quot;American Motors&quot; &gt;American Motors&lt;/option&gt;
<br />
&lt;option value=&quot;Audi&quot; &gt;Audi&lt;/option&gt;
<br />
&lt;option value=&quot;BMW&quot; &gt;BMW&lt;/option&gt;
<br />
...</p></blockquote>
<p>
and ran:
</p>
<blockquote class="code"><p>INSERT INTO Answer (QuestionId, Text, CreatedDate, ModifiedDate) VALUES (2, &apos;Acura&apos;, NOW(), NOW());
<br />
INSERT INTO Answer (QuestionId, Text, CreatedDate, ModifiedDate) VALUES (2, &apos;Alfa Romeo&apos;, NOW(), NOW());
<br />
INSERT INTO Answer (QuestionId, Text, CreatedDate, ModifiedDate) VALUES (2, &apos;American Motors&apos;, NOW(), NOW());
<br />
INSERT INTO Answer (QuestionId, Text, CreatedDate, ModifiedDate) VALUES (2, &apos;Audi&apos;, NOW(), NOW());
<br />
INSERT INTO Answer (QuestionId, Text, CreatedDate, ModifiedDate) VALUES (2, &apos;BMW&apos;, NOW(), NOW());
<br />
...</p></blockquote>
<p>
and now have my own set of Answers with their own IDs. I want a select list where each option has an Answer and its ID from my database. To build this list in MySQL*, I use:
</p>
<blockquote class="code"><p>SELECT CONCAT(&apos;&lt;option value=&quot;&apos; , Id , &apos;&quot;&gt;&apos; , Text , &apos;&lt;/option&gt;&apos;) FROM Answer</p></blockquote>
<p>
which results in:
</p>
<blockquote class="code"><p>&lt;option value=&quot;1&quot;&gt;Acura&lt;/option&gt;
<br />
&lt;option value=&quot;2&quot;&gt;Alfa Romeo&lt;/option&gt;
<br />
&lt;option value=&quot;3&quot;&gt;American Motors&lt;/option&gt;
<br />
&lt;option value=&quot;4&quot;&gt;Audi&lt;/option&gt;
<br />
&lt;option value=&quot;5&quot;&gt;BMW&lt;/option&gt;
<br />
...</p></blockquote>
<p>
* In SQL Server you could write:
</p>
<blockquote class="code"><p>SELECT &apos;&lt;option value=&quot;&apos; + Id + &apos;&quot;&gt;&apos; + Text + &apos;&lt;option&gt;&apos; FROM Answer</p></blockquote> 
      ]]></content>
    </entry>

    <entry>
      <title>WEBDEV: Convert an option list to SQL with TextMate and Regular Expressions</title>
      <link rel="alternate" type="text/html" href="http://www.c77studios.com/webdev_convert_an_option_list_to_sql_with_textmate_and_regular_expressions/" />
      <id>tag:c77studios.com,2007:index/1.19</id>
      <published>2007-07-09T17:51:00Z</published>
      <updated>2007-08-16T02:03:56Z</updated>
      <author>
            <name>Mark</name>
            <email>mjr@c77studios.com</email>
                  </author>

      <content type="html"><![CDATA[
        <p>I grabbed a list of auto manufacturers from another site&#8217;s dropdown menu:
</p>
<blockquote class="code"><p>&lt;option value=&quot;Acura&quot; &gt;Acura&lt;/option&gt;
<br />
&lt;option value=&quot;Alfa Romeo&quot; &gt;Alfa Romeo&lt;/option&gt;
<br />
&lt;option value=&quot;American Motors&quot; &gt;American Motors&lt;/option&gt;
<br />
&lt;option value=&quot;Audi&quot; &gt;Audi&lt;/option&gt;
<br />
&lt;option value=&quot;BMW&quot; &gt;BMW&lt;/option&gt;
<br />
...</p></blockquote>
<p>
With the intention of converting it to SQL for my database.
</p>
<p>
Replacing the first portion of each item is easy: Do a Find &amp; Replace on:
</p>
<blockquote class="code"><p>&lt;option value=&#8221;</p></blockquote>
<p>
replacing it with
</p>
<blockquote class="code"><p>INSERT INTO Answer (QuestionId, Text, CreatedDate, ModifiedDate) VALUES (2, &apos;</p></blockquote>
<p>
The second half requires a bit more than just Find &amp; Replace, though, as each string is different. Fortunately TextMate supports Regular Expressions. The second portion is a Find &amp; Replace on:
</p>
<blockquote class="code"><p>&quot; &gt;.*&lt;\/option&gt;</p></blockquote>
<p>
replacing it with
</p>
<blockquote class="code"><p>&apos;, NOW(), NOW());</p></blockquote>
<p>
leaving us with
</p>
<blockquote class="code"><p>INSERT INTO Answer (QuestionId, Text, CreatedDate, ModifiedDate) VALUES (2, &apos;Acura&apos;, NOW(), NOW());
<br />
INSERT INTO Answer (QuestionId, Text, CreatedDate, ModifiedDate) VALUES (2, &apos;Alfa Romeo&apos;, NOW(), NOW());
<br />
INSERT INTO Answer (QuestionId, Text, CreatedDate, ModifiedDate) VALUES (2, &apos;American Motors&apos;, NOW(), NOW());
<br />
INSERT INTO Answer (QuestionId, Text, CreatedDate, ModifiedDate) VALUES (2, &apos;Audi&apos;, NOW(), NOW());
<br />
INSERT INTO Answer (QuestionId, Text, CreatedDate, ModifiedDate) VALUES (2, &apos;BMW&apos;, NOW(), NOW());
<br />
...</p></blockquote>
<p>
Regular Expression string explained:
</p>
<blockquote class="code"><p>&quot; &gt;</p></blockquote>
<p>
is the end of the option tag.
</p>
<blockquote class="code"><p>.*</p></blockquote>
<p>
is any character (the .) repeated (the *) any number of times, until we hit
</p>
<blockquote class="code"><p>&lt;/option&gt;</p></blockquote>
<p>
with the \ to escape the / character.
</p>
<p>
I grabbed my <a href="http://www.visibone.com/products/browserbook.html" title="VisiBone Browser Book">VisiBone Browser Book</a> to look up syntax. In the past I&#8217;ve also used <a href="http://www.regular-expressions.info/reference.html" title="http://www.regular-expressions.info/reference.html">http://www.regular-expressions.info/reference.html</a> and realtime JavaScript RegEx evaluators such as this one: <a href="http://www.teria.com/~koseki/memo/javascript/realtime_eval.html" title="http://www.teria.com/~koseki/memo/javascript/realtime_eval.html">http://www.teria.com/~koseki/memo/javascript/realtime_eval.html</a>. Keep in mind, though, that a JavaScript evaluator is evaluating RegEx in JavaScript, which may be more or less robust and/or slightly syntactically different than your language of choice.
</p> 
      ]]></content>
    </entry>


</feed>