<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Slicksurface - Tech, Design &amp; SEO Blog</title>
	
	<link>http://www.slicksurface.com/blog</link>
	<description>Observations about technology, design, and search engine optimization by the staff of Slicksurface LLC - a design and technology company located in New York.</description>
	<lastBuildDate>Mon, 15 Apr 2013 13:53:21 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/slicksurface" /><feedburner:info uri="slicksurface" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>40.85777</geo:lat><geo:long>-73.93485</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/</creativeCommons:license><image><link>htttp://www.slicksurface.com/</link><url>http://www.slicksurface.com/resources/logos/feed-logo.jpg</url><title>Slicksurface LLC</title></image><item>
		<title>Memory Leak In 4D’s PROCESS HTML TAGS</title>
		<link>http://feedproxy.google.com/~r/slicksurface/~3/Q-UXtPczgp8/memory-leak-in-4ds-process-html-tags</link>
		<comments>http://www.slicksurface.com/blog/2011-04/memory-leak-in-4ds-process-html-tags#comments</comments>
		<pubDate>Thu, 28 Apr 2011 17:10:25 +0000</pubDate>
		<dc:creator>Jay Harper</dc:creator>
				<category><![CDATA[4D]]></category>

		<guid isPermaLink="false">http://www.slicksurface.com/blog/?p=369</guid>
		<description><![CDATA[I'm now taking the policy that if 4D asks me to do their QC work for them, then I'll post the problem publicly... I'm sorta tired of them not taking quality control seriously. Case and point - I gave them a test case that showed a memory leak when generating HTML documents. They narrowed it [...]]]></description>
				<content:encoded><![CDATA[<p>I'm now taking the policy that if <a href="http://www.4d.com" target="_blank">4D</a> asks me to do their QC work for them, then I'll post the problem publicly... I'm sorta tired of them not taking quality control seriously. Case and point - I gave them a test case that showed a memory leak when generating HTML documents. They narrowed it down to a memory leak in PROCESS HTML TAGS, but then told me to create a simpler test case. I was sorta floored by the request... It's a verified memory leak and they can't be bothered to do their own test case... Remarkable.</p>
<p>So, I've done the test case. Here's the core method... It repeatedly sets 15 variables (5 text, 5 blobs, 5 long inteters), and then calls PROCESS HTML TAGS which composes a simple page using those variables. Some of the text and blobs are a bit large - but nothing that's too big for 4D to handle.</p>
<p>Here's the core method in the database...</p>
<pre>C_TEXT($path_t)
C_TIME($doc)
C_LONGINT($loop_l)

Compiler_Test_Vars 

SET BLOB SIZE(test_template_x;0)
SET BLOB SIZE(test_output_x;0)

$path_t:=System_GetStructureFilePath +"test:test.htm"

If (Test path name($path_t)#Is a document)
ALERT("Can't find "+$path_t)
Else 

DOCUMENT TO BLOB($path_t;test_template_x)

$doc:=Utility_CreateDocument (System_GetStructureFilePath +"test:output:loop-counter.txt")
CLOSE DOCUMENT($doc)

$loop_l:=0

Repeat 

For ($i;1;1000)
  If (Not(Macintosh command down &amp; Macintosh control down))
      //put random variables on the page of different sizes...
    test_text1_t:=Utility_Gibberish (10;0)
    test_text2_t:=Utility_Gibberish (100;0)
    test_text3_t:=Utility_Gibberish (50;0)
    test_text4_t:=Utility_Gibberish (1000;0)
    test_text5_t:=Utility_Gibberish (75;0)

    SET BLOB SIZE(test_blob1_x;0)
    SET BLOB SIZE(test_blob2_x;0)
    SET BLOB SIZE(test_blob3_x;0)
    SET BLOB SIZE(test_blob4_x;0)
    SET BLOB SIZE(test_blob5_x;0)

    TEXT TO BLOB(Utility_Gibberish (10;0);test_blob1_x)
    TEXT TO BLOB(Utility_Gibberish (100;0);test_blob2_x)
    TEXT TO BLOB(Utility_Gibberish (1000;0);test_blob3_x)
    TEXT TO BLOB(Utility_Gibberish (5000;0);test_blob4_x)
    TEXT TO BLOB(Utility_Gibberish (10000;0);test_blob5_x)

    test_longint1_l:=Random
    test_longint2_l:=Random
    test_longint3_l:=Random
    test_longint4_l:=Random
    test_longint5_l:=Random

    PROCESS HTML TAGS(test_template_x;test_output_x)

    BLOB TO DOCUMENT(System_GetStructureFilePath +"test:output:output"+String($i;"0000")+".htm";test_output_x)

    SET BLOB SIZE(test_output_x;0)

  End if
End for
$loop_l:=$loop_l+1

$doc:=Append document(System_GetStructureFilePath +"test:output:loop-counter.txt")
If (Macintosh command down &amp; Macintosh control down)
SEND PACKET($doc;"Loop "+String($loop_l)+" aborted")
Else
SEND PACKET($doc;"Loop "+String($loop_l)+" complete")
End if
CLOSE DOCUMENT($doc)

Until (Macintosh command down &amp; Macintosh control down)

ALERT("Done")
End if</pre>
<p>If you want to see the memory leak in action, <a href="http://www.slicksurface.com/blog/resources/2011/04/MemoryLeak.4dbase.zip">download the test database with the memory leak</a> and run the method test_SimpleCacheLoop and then watch memory usage of 4D - you'll see it go up quite quickly. It's Mac only at the moment. Press Command + Control to end the test or quit 4D. In my tests it went from 57 MB of real memory to over 250 MB of real memory in about a half hour.</p>
<p>My point in all of this is that they need a testing routine that has test cases that stress test every command and function in their product. This is a bug that's simple to identify and catch, but it's been in their product for a long time now and no one has caught it. If a developer catches something like this 4D needs to understand it's their job, not the developer's to get to the bottom of it once the problem is validated and not the result of a coding error on the part of the developer. In the case of a memory leak, 4D should do basic checks (like writing a test database as I did) to validate the error and see if it can be reproduced easily.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/slicksurface?a=Q-UXtPczgp8:yY1HLEfWx3A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=Q-UXtPczgp8:yY1HLEfWx3A:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=Q-UXtPczgp8:yY1HLEfWx3A:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=Q-UXtPczgp8:yY1HLEfWx3A:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=Q-UXtPczgp8:yY1HLEfWx3A:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=Q-UXtPczgp8:yY1HLEfWx3A:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=Q-UXtPczgp8:yY1HLEfWx3A:wF9xT3WuBAs"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=Q-UXtPczgp8:yY1HLEfWx3A:wF9xT3WuBAs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/slicksurface/~4/Q-UXtPczgp8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.slicksurface.com/blog/2011-04/memory-leak-in-4ds-process-html-tags/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.slicksurface.com/blog/2011-04/memory-leak-in-4ds-process-html-tags</feedburner:origLink></item>
		<item>
		<title>Ways In Which Firefox Is Better than Chrome</title>
		<link>http://feedproxy.google.com/~r/slicksurface/~3/b46RXuBFRQQ/ways-in-which-firefox-is-better-than-chrome</link>
		<comments>http://www.slicksurface.com/blog/2011-02/ways-in-which-firefox-is-better-than-chrome#comments</comments>
		<pubDate>Sun, 20 Feb 2011 19:38:39 +0000</pubDate>
		<dc:creator>Jay Harper</dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Firefox]]></category>

		<guid isPermaLink="false">http://www.slicksurface.com/blog/?p=347</guid>
		<description><![CDATA[For a few months now Google's Chrome has been my primary browser. I had been having problems with Firefox and wanted something that was faster and more stable. Chrome did seem a lot faster than Firefox and stability seemed better too. But then little things kept bugging me about it and I'd have to switch [...]]]></description>
				<content:encoded><![CDATA[<p>For a few months now Google's Chrome has been my primary browser. I had been having problems with Firefox and wanted something that was faster and more stable. Chrome did seem a lot faster than Firefox and stability seemed better too. But then little things kept bugging me about it and I'd have to switch back to Firefox. Here are some of the items I've encountered..</p>
<h4>Chrome doesn't display XML documents nearly as well as Firefox</h4>
<p>Firefox uses a default stylesheet whenever it encounters an XML document. Here's an example (the server info document from the Wowza streaming server):</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-349" title="wowza firefox" src="http://www.slicksurface.com/blog/resources/2011/02/wowza-firefox.jpg" alt="wowza firefox" width="378" height="226" /></p>
<p>Chrome, on the other hand, treats XML as HTML and does a horrible job displaying it...</p>
<p style="text-align: center;"><a href="http://www.slicksurface.com/blog/resources/2011/02/wowza-chrome.jpg"><img class="aligncenter size-full wp-image-348" title="wowza chrome" src="http://www.slicksurface.com/blog/resources/2011/02/wowza-chrome.jpg" alt="wowza chrome" width="521" height="19" /></a></p>
<p>Firefox's rendering of the XML document is great - very readable and usable. In contrast, Chrome's rendering of XML aweful.</p>
<h4>Chrome doesn't let you get the URL of an RSS feed</h4>
<p>In Chrome, when you view an RSS feed it blanks out the URL. If you need the URL you can't get it. Here's an example in Chrome...</p>
<p style="text-align: center;"><img class="aligncenter size-large wp-image-354" title="rss chrome" src="http://www.slicksurface.com/blog/resources/2011/02/rss-chrome1-575x388.jpg" alt="rss chrome" width="575" height="388" /></p>
<p>Notice there's no URL at the top. Now here's Firefox which makes it easy to get the URL...</p>
<p style="text-align: center;"><img class="aligncenter size-large wp-image-353" title="rss firefox" src="http://www.slicksurface.com/blog/resources/2011/02/rss-firefox1-575x534.jpg" alt="rss firefox" width="575" height="534" /></p>
<h4>Chrome doesn't display the page title clearly</h4>
<p>This one is somewhat ironic. The most important element on any page - in order to get it to rank in Google, is the page title. Yet, Google doesn't clearly display the page title. They place the title in the tab at the top of the window. If your title is long, or you have many tabs open you don't see the entire title. You can get it if you hover over the tab, but it's not clearly displayed like it is in other browsers. Here is an example of the problem in Chrome. I've hovered over one of the tabs to see the title, but it takes a while for the hover text to show up - it's not easy to see.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-356" title="title chrome" src="http://www.slicksurface.com/blog/resources/2011/02/title-chrome.jpg" alt="" width="575" height="64" /></p>
<p>And here is the title clearly shown in Firefox...</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-355" title="title firefox" src="http://www.slicksurface.com/blog/resources/2011/02/title-firefox.jpg" alt="title firefox" width="575" height="104" /></p>
<p>While it may not seem important, if you're an SEO, it's VERY important.</p>
<h4>Chrome's status bar just isn't as good or useful as Firefox's</h4>
<p>Chrome tried to save vertical space. They don't show the page title (see above) and they don't really have much of a status bar at the bottom of the browser. In fact there is no status bar at all until you scroll over a link, then you get a small status bar that doesn't show the entire URL (though it expands after a few seconds of hovering).</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-358" title="status bar chrome" src="http://www.slicksurface.com/blog/resources/2011/02/status-bar-chrome.jpg" alt="status bar chrome" width="446" height="73" /></p>
<p>By contrast in firefox you not only get the entire URL, but you can have all sorts of helpful stuff at the bottom to give you other information about the page...</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-357" title="status bar firefox" src="http://www.slicksurface.com/blog/resources/2011/02/status-bar-firefox.jpg" alt="status bar firefox" width="550" height="19" /></p>
<p>As a web developer and SEO all the info is invaluable to me. Yes, there is an SEO plugin that you can use, but you have to click on something to see the information - it's not easy to see.</p>
<h4>Chrome discontinued native support for H.264</h4>
<p>Last year Google bought the company On2 and then proceded to give the crown jewel of the companyaway for free (the video codec VP8/WebM). While it was a nice move, they then discontinued support in Chrome for the most viable competing video codec - H.264 which is more widely used and preferred by many people. Yes, H.264 is still supportedin Chrome via Flash, but native HTML5 support is gone. While it's great that Google gave away VP8/WebM, it's a bit mercenary that they're trying to undermine H.264. All Google managed to do is extend the life of Flash and delay the adoption of native HTML5 video.</p>
<h4>Chrome has problems with some PDFs</h4>
<p>With Chrome I can't always download some PDFs. When I try to get a PDF statement on Chase's website something converts it to HTML, which defeats the purpose completely.</p>
<h4>There are no ways in which Chrome is all that much better than Firefox</h4>
<p>While I can name a bunch of ways Firefox is better than Chrome, after months of using Chrome as my primary browser I can't really think of any ways in which Chrome is better than Firefox. Yes, I had some stability and speed issues with Firefox, but I'm starting to see similar problems with Chrome. It won't always ask if I want to remember a password, and sometimes it forgets passwords. I think my primary problem with Firefox was that I was using a profile that had been upgraded since the days when Firefox and Thunderbird were merged and called Netscape Navigator. I think my user profile had become "dirty" and a clean install of Firefox will fix my problems.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/slicksurface?a=b46RXuBFRQQ:89qr1OHoCb4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=b46RXuBFRQQ:89qr1OHoCb4:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=b46RXuBFRQQ:89qr1OHoCb4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=b46RXuBFRQQ:89qr1OHoCb4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=b46RXuBFRQQ:89qr1OHoCb4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=b46RXuBFRQQ:89qr1OHoCb4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=b46RXuBFRQQ:89qr1OHoCb4:wF9xT3WuBAs"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=b46RXuBFRQQ:89qr1OHoCb4:wF9xT3WuBAs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/slicksurface/~4/b46RXuBFRQQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.slicksurface.com/blog/2011-02/ways-in-which-firefox-is-better-than-chrome/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://www.slicksurface.com/blog/2011-02/ways-in-which-firefox-is-better-than-chrome</feedburner:origLink></item>
		<item>
		<title>4D’s direction with v13 and Wakanda</title>
		<link>http://feedproxy.google.com/~r/slicksurface/~3/1CPKdLlsCYg/4ds-direction-with-v13-and-wakanda</link>
		<comments>http://www.slicksurface.com/blog/2010-10/4ds-direction-with-v13-and-wakanda#comments</comments>
		<pubDate>Thu, 14 Oct 2010 12:16:20 +0000</pubDate>
		<dc:creator>Jay Harper</dc:creator>
				<category><![CDATA[4D]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[4D-summit]]></category>

		<guid isPermaLink="false">http://www.slicksurface.com/blog/?p=341</guid>
		<description><![CDATA[UPDATE: A couple days after writing this blog post, Jean-Michel Biraghi, 4D's Director of Marketing, pulled me aside for a chat. I've revised the blog post based on that discussion... I'm not doing a blow-by-blow blog of 4D Summit this year. But I am twittering things blow-by-blow - Check out my Twitter feed for all [...]]]></description>
				<content:encoded><![CDATA[<p><em>UPDATE: A couple days after writing this blog post, Jean-Michel Biraghi, 4D's Director of Marketing, pulled me aside for a chat. I've revised the blog post based on that discussion...</em></p>
<p>I'm not doing a blow-by-blow blog of 4D Summit this year. But I am twittering things blow-by-blow - Check out my Twitter feed for all the little details - <a href="http://www.twitter.com/SummitNotes " target="_blank">twitter.com/SummitNotes</a> - instead what I want to blog is sorta a birds eye view of what's going on...</p>
<p><strong>The future of 4D is Javascript development</strong></p>
<p>A lot of time was spent going over 4D's new/future product - Wakanda. Wakanda is an object-oriented Javascript development environment that greatly simplifies the development of RIAs. It will be to web development what 4D is to client/server - and integrated approach where you can get a lot done relatively easily. Like other pure Javascript solutions, Wakanda is not for public facing web sites where you want organic traffic from search engines - there is nothing of substance in the HTML document for search engine spiders to digest. Instead, it's appropriate for use once a person has logged in - in the non-public areas of a web site, or for powering ancillary content in iFrames. Wakanda will take client-server like functionality and put it onto the web as easily as you deploy 4D today.</p>
<p>It's important to note that Wakanda is not a future version of 4D, though they do have plans to enable it to be integrated in a 4D environment. It's more like 4D Web 2.0 Pack on massive doses of steroids.</p>
<p><strong>4D is doing well - and that may be a bad thing...</strong></p>
<p>That's a little hyperbole, but let me explain... 4D SAS/Inc now has $9M sitting in the bank. They could go for 6 months collecting no revenue and still be OK. In a way that's good - it means 4D will be around for a long time. But there's a downside to it as well - they're not hungry. Jean-Michel made note of that comment and swore they were hungry. In rethinking it, Wakanda is a huge change for 4D and 4D is sinking so much money into it that I'm sure there is a certain hunger to make sure it's not a flop. Whether there's 'hunger' the way a New Yorker (like me) would define the term, has yet to be determined...</p>
<p>What is abundantly clear is that 4D is a technology driven company. You may think that's a good thing for a technology company, but what it means is that they're not a sales and marketing driven company. Yes, they're relatively innovative, but there isn't the deep desire to sell more or get more marketshare. However, while they're developer community feels like it's getting smaller, their sales are up, so they do seem to be doing something right when it comes to sales. It would appear they're getting (possibly) fewer customers to make bigger and bigger investments in their products.</p>
<p>Like someone selling books, 4D is in the publishing business in that the first product they sell costs them millions of dollars and every product after that is close to zero cost. Every additional customer they get is almost pure profit. I just wish they'd be a more aggressive in their attempts to get additional sales. Maybe they are and I just don't see it...</p>
<p><strong>Can 4D get marketshare for Wakanda?</strong></p>
<p>For years I and many other 4D developers were mystified by 4D's apparent lack of a marketing strategy. For example, try to find a description of 4D on 4D.com - it's not there. They have a paragraph or so that gives and overview, and they have descriptions of each product, but I'm talking about an overview page that someone with industry experience (a potential customer) could look at and understand where 4D fits into the technical landscape. Even the product descriptions - they describe the feature list, but don't give an overview of where that product fits into the overall concept. Take <a href="http://4d.com/us/products/4dv12/4dserver.html" target="_blank">the page on 4D Server</a> as an example - it has a features list including some of the ways you can interact with 4D Server, but there's no diagram or in-depth details explaining all the ways you can connect to a 4D Server (client/server, web, SQL, JSON, web services, etc.), nor are there benchmarks descriptions of 4D Server's capabilities and limitations. Giving customers a really good understanding of what your product is all about is Goal One of any website, yet the 4D website fails at that really basic objective. That says a lot...</p>
<p>But in their defense, the comment was made that getting additional marketshare in a mature market like client/server is extremely difficult and expensive. With their current product their lack of marketing almost makes sense (but not quite). They seem to be doing a decent job with actually selling 4D (revenues are up). But the real problem is that they've now got a new product in a competitive market, yet so far they haven't demonstrated a level of marketing savvy equal to that of their competitors.</p>
<p>It goes beyond not describing the product on the website. Let's take another really basic example - the name Wakanda... Apparently they're getting out of the technology business and they're <a href="http://www.wakanda.com/" target="_blank">getting into the resort business and moving to upstate New York</a>. I know choosing a product name is extremely difficult, but these days you don't give a product a name unless you own the domain name. It's one thing to have a code name early on - Wakanda would have been a perfectly fine name at last year's Summit where the product was largely conceptual, but they presented Wakanda as a serious product they were going to launch in the not-t0o-distant future and they don't own wakanda.com. Jean-Michel told me that Wakanda means "the magic within" (in Sioux) and that they hired an agency to help them find the name. I know it's a difficult process but personally I'd offer the resort good money for the domain name or consider using another name - but that's just me.</p>
<p>Bottom line, I'm not convinced 4D has the skills they need to really make Wakanda succeed. There are plenty of other ways I could go into about how 4D's marketing could use some help - sites that aren't SEO'd, sites that aren't crawlable by search engines, etc., and just the general blank looks you get when you say you work with 4D. I hope they can get their act together for Wakanda, but I'm skeptical.</p>
<p><strong>No big changes to 4D in the near future</strong></p>
<p>At the summit two years ago v11 had just been released and they made it very clear that the 4D language was now 4D's big problem. The database engine itself had been reworked and was robust and modern, but the language, being single threaded on the OS level, was a significant problem - especially on server since all stored procedures and web requests had to queue in line to get completed. They promised that in "the next version" that would be fixed. Well, v12 is out and it's not fixed, and it won't be fixed in v13 either. I suspect Wakanda fixes it, but that's  a different product.</p>
<p>They were pretty clear that all the future versions of 4D in the next few years will be incremental. That means easy upgrades, but they won't really be fixing the product's core problem. Honestly, I'm hugely disappointed, but I guess it is what it is...</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/slicksurface?a=1CPKdLlsCYg:1T83M6UVCas:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=1CPKdLlsCYg:1T83M6UVCas:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=1CPKdLlsCYg:1T83M6UVCas:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=1CPKdLlsCYg:1T83M6UVCas:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=1CPKdLlsCYg:1T83M6UVCas:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=1CPKdLlsCYg:1T83M6UVCas:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=1CPKdLlsCYg:1T83M6UVCas:wF9xT3WuBAs"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=1CPKdLlsCYg:1T83M6UVCas:wF9xT3WuBAs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/slicksurface/~4/1CPKdLlsCYg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.slicksurface.com/blog/2010-10/4ds-direction-with-v13-and-wakanda/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.slicksurface.com/blog/2010-10/4ds-direction-with-v13-and-wakanda</feedburner:origLink></item>
		<item>
		<title>Google Images Now Also Served From WWW</title>
		<link>http://feedproxy.google.com/~r/slicksurface/~3/jltJl225WTA/google-images-now-also-served-from-www</link>
		<comments>http://www.slicksurface.com/blog/2010-04/google-images-now-also-served-from-www#comments</comments>
		<pubDate>Wed, 28 Apr 2010 16:09:54 +0000</pubDate>
		<dc:creator>Jay Harper</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Analytics]]></category>
		<category><![CDATA[Image Search]]></category>

		<guid isPermaLink="false">http://www.slicksurface.com/blog/?p=337</guid>
		<description><![CDATA[A couple weeks ago I got quite worried about the Google Images traffic on one of my sites... That's a pretty dramatic drop. I started going through all the scenarios of what might be happening. Then a couple days later I noticed this... In other words, at the same time there was a drop in [...]]]></description>
				<content:encoded><![CDATA[<p>A couple weeks ago I got quite worried about the Google Images traffic on one of my sites...</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-339" title="google images traffic down" src="http://www.slicksurface.com/blog/resources/2010/04/google-images-traffic-down.jpg" alt="google images traffic down" width="590" height="231" /></p>
<p>That's a pretty dramatic drop. I started going through all the scenarios of what might be happening. Then a couple days later I noticed this...</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-338" title="google www traffic up" src="http://www.slicksurface.com/blog/resources/2010/04/google-www-traffic-up.jpg" alt="google www traffic up" width="590" height="228" /></p>
<p>In other words, at the same time there was a drop in traffic from images.google.com, there was an uptick in traffic from www.google.com/imgres. This means Google is now serving Google Images content off www.google.com.</p>
<p>So I didn't do anything wrong, and my Google Images traffic is just fine... Now, if <a href="http://www.slicksurface.com/blog/2008-06/google-images-google-analytics-frames">Google Analytics could only learn how to properly count Google Images traffic</a> we'd be set.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/slicksurface?a=jltJl225WTA:JN3O_v3rC7k:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=jltJl225WTA:JN3O_v3rC7k:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=jltJl225WTA:JN3O_v3rC7k:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=jltJl225WTA:JN3O_v3rC7k:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=jltJl225WTA:JN3O_v3rC7k:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=jltJl225WTA:JN3O_v3rC7k:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=jltJl225WTA:JN3O_v3rC7k:wF9xT3WuBAs"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=jltJl225WTA:JN3O_v3rC7k:wF9xT3WuBAs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/slicksurface/~4/jltJl225WTA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.slicksurface.com/blog/2010-04/google-images-now-also-served-from-www/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.slicksurface.com/blog/2010-04/google-images-now-also-served-from-www</feedburner:origLink></item>
		<item>
		<title>Partners With Parents Tutoring Service Launches New Site</title>
		<link>http://feedproxy.google.com/~r/slicksurface/~3/7HOBE3zAMjw/partners-with-parents-tutoring-service-launches-new-site</link>
		<comments>http://www.slicksurface.com/blog/2009-09/partners-with-parents-tutoring-service-launches-new-site#comments</comments>
		<pubDate>Mon, 28 Sep 2009 17:36:28 +0000</pubDate>
		<dc:creator>Jay Harper</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Feeds]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Search Marketing]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Feedburner]]></category>
		<category><![CDATA[SEO/SEM]]></category>
		<category><![CDATA[Web Analytics]]></category>
		<category><![CDATA[web-site-design]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.slicksurface.com/blog/?p=316</guid>
		<description><![CDATA[Slicksurface recently launched a new website for Partners With Parents Tutoring Service, located in New York City. This site was a particularly interesting project for a number of reasons. Jesse Gerber, co-founder of Partners With Parents is a neighbor and good friend. He was initially resistant to a redesign partly due to the cost of [...]]]></description>
				<content:encoded><![CDATA[<p>Slicksurface recently launched a new website for <a href="http://www.partnerswithparents.com">Partners With Parents Tutoring Service</a>, located in New York City. This site was a particularly interesting project for a number of reasons.</p>
<p><a title="Jesse Gerber biography" href="http://www.partnerswithparents.com/about-us/staff-biographies">Jesse Gerber</a>, co-founder of Partners With Parents is a neighbor and good friend. He was initially resistant to a redesign partly due to the cost of the redesign and implementation and partly due to a certain level of fear of how a new website might change the nature of his business.  The focus of his fear was the possibility of an overwhelming number of inquiries without the necessary support or conversion to real customers. After much conversation, we began the redesign process over the summer.<span id="more-316"></span></p>
<p>We decided to go with a <a href="http://www.wordpress.org">WordPress-driven website</a>, which would give the company the flexibility to change the content on their own, without them needing to come back to us every time they wanted to update a page, or add new information.</p>
<p>Partners With Parents has been in business for over a decade. They specialize in custom private tutoring, with the tutors preparing lessons suited to the each individual's needs and educational environment. They have also had much <a title="test prep tutoring" href="http://www.partnerswithparents.com/services/test-preparation" target="_self">success in test preparation</a>, like the SAT, Regents, AP tests, GRE, MCAT, LSAT and others. Additionally they have <a title="Experienced homeschooling service" href="http://www.partnerswithparents.com/services/homeschooling">extensive experience in homeschooling</a> children with special needs and unique situations.</p>
<p>I took this opportunity to begin a program of my own, an internship program for my web design students. A talented student, Nusrat Bintun, was Slicksurface's first intern. She showed great initiative, and where she lacked in skill and experience, she made up for with enthusiasm and consistency. She was particularly involved with helping to develop the illustrations used on the site. By the end, she gained additional skills in photoshop and illustrator, plus received insight in working with a real client.</p>
<p>An interesting thing to note about this redesign is that it promised to be easy to improve the performance of the site. The previous designer had very little experience creating real professional websites. So instead of designing the pages so that the images were images, and the text was html, he made the text into images as well.  There was basically no text anywhere on the site for the search engines to index.</p>
<p>Two weeks following the launch, we were fully indexed by Google.  We were not indexed by the other search engines, but we knew that would come in time. Partners With Parents immediately ranked for "New York City tutoring" and "NYC tutoring" falling on page 4 and 3 respectively. We now are guiding them in content development to rank for other relevant search terms like "<a href="http://www.partnerswithparents.com/services/homeschooling">New York City homeschooling</a>" and "<a href="http://www.partnerswithparents.com/services/test-preparation">test prep</a>".</p>
<p>Although the site has been indexed fully, the traffic hasn't increased by leaps and bounds in the first month following launch. In studying Google trends, "New York City tutoring" does not have enough data to even warrant a chart. "NYC tutoring" ranks very well with a Brooklyn audience, although "Brooklyn tutoring" does not have enough data to warrant a chart. For just "tutoring" or "tutoring service", the New York audience is in the top 10.</p>
<p>Surprisingly, they immediately received <a href="http://www.partnerswithparents.com/find-a-tutor">requests for tutors</a>, had <a href="http://www.partnerswithparents.com/contact">tutors inquiring about positions</a>, and had subscriptions to the <a href="http://feedburner.google.com/fb/a/mailverify?uri=PartnersWithParents&amp;amp;loc=en_US&quot;">automatic email updates</a> (see description below).</p>
<p>After we have ranked for the key search terms, the next goal is to work towards getting PartnersWithParents.com to show up on the first page for them.</p>
<p>Partners With Parents is looking to build a community among parents, educators, support professionals, and themselves. They decided that one way they would do this is to regularly write posts on everything including <a href="http://www.partnerswithparents.com/tutoring/education">articles about education</a> and <a href="http://www.partnerswithparents.com/tutoring/parenting">parenting</a>, <a href="http://www.partnerswithparents.com/tutoring/new-york-city-families">family challenges and things to do in New York City</a>, and <a href="http://www.partnerswithparents.com/tutoring/stress-and-anxiety">parents and children dealing with stress and anxiety</a>.</p>
<p>Finally, we also implemented <a href="http://www.feedburner.com">Feedburner</a> on this site.  Because we used blog software to run it, the site inherently has a feed.  We've taken advantage of this by inviting users to subscribe to regular updates of the site. Whenever a new blog post is written, those who have subscribed will receive emails automatically of the full blog posts. An inexpensive feature that keeps people reminded of the company's services and expertise.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/slicksurface?a=7HOBE3zAMjw:-PGP4yY0d0c:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=7HOBE3zAMjw:-PGP4yY0d0c:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=7HOBE3zAMjw:-PGP4yY0d0c:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=7HOBE3zAMjw:-PGP4yY0d0c:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=7HOBE3zAMjw:-PGP4yY0d0c:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=7HOBE3zAMjw:-PGP4yY0d0c:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=7HOBE3zAMjw:-PGP4yY0d0c:wF9xT3WuBAs"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=7HOBE3zAMjw:-PGP4yY0d0c:wF9xT3WuBAs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/slicksurface/~4/7HOBE3zAMjw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.slicksurface.com/blog/2009-09/partners-with-parents-tutoring-service-launches-new-site/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.slicksurface.com/blog/2009-09/partners-with-parents-tutoring-service-launches-new-site</feedburner:origLink></item>
		<item>
		<title>Clients Who Try To Cut Down The Price</title>
		<link>http://feedproxy.google.com/~r/slicksurface/~3/VSSxoMM7M6A/clients-who-try-to-cut-down-the-price</link>
		<comments>http://www.slicksurface.com/blog/2009-06/clients-who-try-to-cut-down-the-price#comments</comments>
		<pubDate>Thu, 04 Jun 2009 16:56:13 +0000</pubDate>
		<dc:creator>Jay Harper</dc:creator>
				<category><![CDATA[Business Issues]]></category>

		<guid isPermaLink="false">http://www.slicksurface.com/blog/?p=314</guid>
		<description><![CDATA[One of the things I learned many years ago was that if a client balks at the price, they're a problem client. There are exceptions, of course, but some clients do this routinely - they're the ones I'm talking about. IMHO, those clients are almost never profitable. The same can be true of clients who [...]]]></description>
				<content:encoded><![CDATA[<p>One of the things I learned many years ago was that if a client balks at the price, they're a problem client. There are exceptions, of course, but some clients do this routinely - they're the ones I'm talking about. IMHO, those clients are almost never profitable.<span id="more-314"></span></p>
<p>The same can be true of clients who just can't afford you. They want a $15,000 web site for $4,000 and they think they're spending a lot and should get all the bells and whistles. Again, there are exceptions to that rule as well, but generally it's true. The exception are people who understand your value, but can't afford you, but make it clear they're really grateful that you're cutting them a deal. But they're maybe 1 in 20 people in this group.</p>
<p>Here's a video from YouTube that puts a funny slant on it. If you prefer, you can <a href="http://www.youtube.com/watch?v=R2a8TRSgzZY" target="_blank">watch it in HD</a> on YouTube...</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="560" height="340" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/R2a8TRSgzZY&amp;hl=en&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="560" height="340" src="http://www.youtube.com/v/R2a8TRSgzZY&amp;hl=en&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>In these dire economic times it's tempting to take on clients - even when they can't come close to affording you. We had to turn down an interesting project lately because we got this sorta bad vibe off it. Just be careful - you may be better turning down the work.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/slicksurface?a=VSSxoMM7M6A:ZaC2m8Sxmsg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=VSSxoMM7M6A:ZaC2m8Sxmsg:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=VSSxoMM7M6A:ZaC2m8Sxmsg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=VSSxoMM7M6A:ZaC2m8Sxmsg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=VSSxoMM7M6A:ZaC2m8Sxmsg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=VSSxoMM7M6A:ZaC2m8Sxmsg:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=VSSxoMM7M6A:ZaC2m8Sxmsg:wF9xT3WuBAs"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=VSSxoMM7M6A:ZaC2m8Sxmsg:wF9xT3WuBAs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/slicksurface/~4/VSSxoMM7M6A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.slicksurface.com/blog/2009-06/clients-who-try-to-cut-down-the-price/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.slicksurface.com/blog/2009-06/clients-who-try-to-cut-down-the-price</feedburner:origLink></item>
		<item>
		<title>How Can Yahoo!’s Spam Filter Be THIS Bad?</title>
		<link>http://feedproxy.google.com/~r/slicksurface/~3/X32rVXGPIKg/how-can-yahoos-spam-filter-be-this-bad</link>
		<comments>http://www.slicksurface.com/blog/2009-05/how-can-yahoos-spam-filter-be-this-bad#comments</comments>
		<pubDate>Sat, 30 May 2009 14:06:19 +0000</pubDate>
		<dc:creator>Jay Harper</dc:creator>
				<category><![CDATA[Spam]]></category>

		<guid isPermaLink="false">http://www.slicksurface.com/blog/?p=306</guid>
		<description><![CDATA[Please explain to me how it is that Yahoo! can't figure out that the following e-mail messages are spam... It boggles my mind... Example 1: From: Jasmine Carter &#60;eshulsenerman55@yahoo.co.uk&#62; (was this sent from Yahoo! mail? Wouldn't the user hve a bad history?) Subject: PrettybtP0rn0qshotswz NkLwEcPfjuBSvtYzMh Body: http://74ce532cee461e8c.faceplanesize.com!}TrKbR3ineUtLzxINIU PJBgeXVHxUdnRToTQMqagL Example 2: From: Shelby Taylor &#60;garlettabearden94@yahoo.co.uk&#62; (again, [...]]]></description>
				<content:encoded><![CDATA[<p>Please explain to me how it is that Yahoo! can't figure out that the following e-mail messages are spam... It boggles my mind...</p>
<p><strong>Example 1:</strong></p>
<p><em>From:</em> <span class="cgSelectable" title="View all messages from this sender">Jasmine Carter &lt;eshulsenerman55@yahoo.co.uk&gt; (was this sent from Yahoo! mail? Wouldn't the user hve a bad history?)<br />
</span></p>
<p><em>Subject:</em> <span class="cgSelectable" style="cursor: pointer;" title="View all messages with this subject">PrettybtP0rn0qshotswz NkLwEcPfjuBSvtYzMh</span></p>
<p><em>Body:</em> <a href="javascript:alert('This was a link');"><span id="lw_1243691572_0" class="yshortcuts">http://74ce532cee461e8c.faceplanesize.com</span></a>!}TrKbR3ineUtLzxINIU   PJBgeXVHxUdnRToTQMqagL<span id="more-306"></span></p>
<p><strong>Example 2: </strong></p>
<p><em>From:</em> <span class="cgSelectable cgSelectable-over" title="View all messages from this sender">Shelby Taylor &lt;garlettabearden94@yahoo.co.uk&gt; (again, a yahoo.co.uk e-mail address)<br />
</span></p>
<p><em>Subject:</em> <span class="cgSelectable" style="cursor: pointer;" title="View all messages with this subject">-SEX-U-A-LY_EX-PL_I_C_It SPzNynCLWiTnPJyPJmvU</span></p>
<p><em>Body:</em> NpZnutWnmUdgdZuJZDfUVp{)<a href="javascript:alert('This was a link');"><span id="lw_1243691838_0" class="yshortcuts">dad4479785c30468.yessoontalk.com</span></a>}&amp;bcRREwMbmEcGfdoTH   NgRIcnHXqsmQIZ1T</p>
<p><strong>Example 3: </strong></p>
<p><em>From:</em><span class="cgSelectable cgSelectable-over" title="View all messages from this sender"> F-r_eePodrnoMotionpictureq &lt;karynmarshi86@yahoo.co.uk&gt;</span></p>
<p><em>Subject:</em> [ No Subject ]</p>
<p><em>Body:</em> hzxqipfrguknzsip{<a href="javascript:alert('This was a link');"><span id="lw_1243692096_0" class="yshortcuts">http://13e0754d679f4cd1.questionexamplehouse.com</span></a>}!hjgfarfbHectcGu   rPwwoRWqHyVpqXyPNrcIcVG</p>
<p>I just don't get it. How can their spam filters miss these e-mails? It can't be that hard to write a spam filter to detect messages like these... I wonder if Yahoo! UK isn't having some sort of problem - all the e-mails appear to come from there.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/slicksurface?a=X32rVXGPIKg:YLBc_Xewf_8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=X32rVXGPIKg:YLBc_Xewf_8:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=X32rVXGPIKg:YLBc_Xewf_8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=X32rVXGPIKg:YLBc_Xewf_8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=X32rVXGPIKg:YLBc_Xewf_8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=X32rVXGPIKg:YLBc_Xewf_8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=X32rVXGPIKg:YLBc_Xewf_8:wF9xT3WuBAs"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=X32rVXGPIKg:YLBc_Xewf_8:wF9xT3WuBAs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/slicksurface/~4/X32rVXGPIKg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.slicksurface.com/blog/2009-05/how-can-yahoos-spam-filter-be-this-bad/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.slicksurface.com/blog/2009-05/how-can-yahoos-spam-filter-be-this-bad</feedburner:origLink></item>
		<item>
		<title>Changing the look of your page for mobile devices and printing</title>
		<link>http://feedproxy.google.com/~r/slicksurface/~3/AzWimEn_m7w/changing-the-look-of-your-page-for-mobile-devices-and-printing</link>
		<comments>http://www.slicksurface.com/blog/2008-12/changing-the-look-of-your-page-for-mobile-devices-and-printing#comments</comments>
		<pubDate>Thu, 04 Dec 2008 19:23:03 +0000</pubDate>
		<dc:creator>Jay Harper</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Mobile Browsers]]></category>
		<category><![CDATA[CityTech ADV 4850]]></category>

		<guid isPermaLink="false">http://www.slicksurface.com/blog/?p=301</guid>
		<description><![CDATA[Your site may look great on screen, but have you thought about what it looks like when it's printed or what it looks like when a mobile device accesses it? Take a moment and print a page from your site - you might be surprised with what comes out of the printer. If you have [...]]]></description>
				<content:encoded><![CDATA[<p>Your site may look great on screen, but have you thought about what it looks like when it's printed or what it looks like when a mobile device accesses it? Take a moment and print a page from your site - you might be surprised with what comes out of the printer.<span id="more-301"></span></p>
<p>If you have white or off-white text on a dark background chances are nothing will come out at all since many browsers don't print the background color - so you wind up printing white on white. If your design depends on things like background colors, chances are it won't look the way you want it to when it's printed. Going to a grayscale color palette may cause problems as well. Add to that that Flash areas probably won't print. And the biggest problem may be the width of your web page - not all web browsers shrink the page to fit on the piece of paper and if your page is wider than 675px you may have a serious problem.</p>
<p>When it comes to mobile devices there are a number of issues...</p>
<p>While the iPhone and some other devices can deal with full size web pages, many can't, an even for devices that can it requires a lot of zooming in and zooming out and can be a bad user experience for the customer.</p>
<p>Then there's the issue of the "weight" of a page. With broadband connections being pretty standard for computers these days web designers don't think about the weight of their pages, but for mobile devices it's critical - most are on super slow network connections and even ones with 3G capabilities may not be in a location that has 3G speeds.</p>
<p>And lastly, people on mobile devices are generally looking for different things than people who are on a computer. They're far more likely to be looking for an address or phone number than a person using a computer.</p>
<p>The reason why printing and mobile devices are connected is because the same two strategies are used to address both problems - 1) alternate stylesheets, and 2) alternate pages - which you use really depends on your situation and how good of a solution you want to implement for printing and mobile devices. If you can't imagine anyone ever printing a page from your web site, then you don't need to spend much time implementing a solution.</p>
<p><em>Alternate Stylesheets</em></p>
<p>When you specify a stylesheet in HTML you typically have a link tag that looks like this:</p>
<p>&lt;link rel="stylesheet" href="/resources/main.css" type="text/css"&gt;</p>
<p>If you've done some reading you may know that there's a "media" attribute that can be added to the link tag which would change it to look something like this:</p>
<p>&lt;link rel="stylesheet" href="/resources/main.css" type="text/css" media="all"&gt;<br />
&lt;link rel="stylesheet" href="/resources/screen.css" type="text/css" media="screen"&gt;<br />
&lt;link rel="stylesheet" href="/resources/print.css" type="text/css" media="print"&gt;<br />
&lt;link rel="stylesheet" href="/resources/mobile.css" type="text/css" media="handheld"&gt;</p>
<p>The media attribute is the key to what we're talking about here. In the example above styles that will be used in all circumstances are defined in main.css. Styles that will only be used on computers are defined in screen.css. Styles that are only used for printing in print.css. And lastly styles that are only used by mobile devices in mobile.css. So when displayed on a computer main.css and screen.css will be loaded and print.css and mobile.css will be ignored, and so on...</p>
<p>Now think about the things you might want to change depending on how it's being used... Since you can't click on a nav bar on a printed page, you may want to hide them completely with display:none when printing. Or you may want to change the width of the page from an absolute value to 100% for printing and mobile devices. Or you may eliminate things like background images for printing and mobile devices. There's a lot you can customize.</p>
<p><em>Alternate Content</em></p>
<p>While having an alternate stylesheet is a quick and easy way to customize the look and feel for printing or mobile devices and it's usually better than doing nothing at all, it's often inadequate. The issue is the HTML document you're working with. You may not be able to do everything you want to do with CSS, or the page may just be too heavy to do well on a mobile device.</p>
<p>Remember, the general rule is to shoot for a total page weight (including CSS and graphics) of less than 20Kb when making a page for mobile devices. Pages over that weight will be penalized by the mobile search engines.</p>
<p>In fact there are many factors you should take into consideration when designing a page for a mobile device. The nav bar is just one example - it should be kept simple and put at both the top and bottom of the page, and possibly interspersed in the middle of the page if the page is long. There's a lot to properly designing a page for a mobile device (including special doc types). I highly recommend you read up on the subject before you go and spend time doing it the wrong way.</p>
<p>To implement an alternate page for printing or for a mobile device once again you use a link tag, but this time it's not rel="stylesheet" it's rel="alternate" and will look something like this...</p>
<p>&lt;link rel="alternate" media="print" type="text/html" href="/image/detail-print.htm?variantid=2983" /&gt;</p>
<p>To see that in action. The original page was <a href="http://www.netterimages.com/image/2983.htm" target="_blank">a page on Netter Images showing an illustration of malignant tumors</a>. <a rel="nofollow" href="http://www.netterimages.com/image/detail-print.htm?variantid=2983" target="_blank">The alternate page used for printing</a> scales the image down, uses desaturated header graphics, and presents the data on the page in a less interactive manner that looks like a printed document.</p>
<p>One thing you should be concerned with is the issue of duplicate content. For alternate versions used for printing, you'll want to either specify nofollow in a robots meta tag, or block access to the file completely with robots.txt. With mobile versions it's more complicated because you want spiders to crawl, but want the search engine to understand which page is targeted to which audience. You can try to use robots.txt to only allow mobile spiders to see the mobile pages, but that may be more trouble than it's worth.</p>
<p><em>Other Uses</em></p>
<p>Alternate stylesheets and alternate pages are important to the visually handicapped. The same strategies we used here are used to create pages that are friendly to them - just use media="aural". CSS supports "voices" - so you can specify the type of voice you think is approrpriate for you content, etc.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/slicksurface?a=AzWimEn_m7w:sBnpVSb_dVw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=AzWimEn_m7w:sBnpVSb_dVw:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=AzWimEn_m7w:sBnpVSb_dVw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=AzWimEn_m7w:sBnpVSb_dVw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=AzWimEn_m7w:sBnpVSb_dVw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=AzWimEn_m7w:sBnpVSb_dVw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=AzWimEn_m7w:sBnpVSb_dVw:wF9xT3WuBAs"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=AzWimEn_m7w:sBnpVSb_dVw:wF9xT3WuBAs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/slicksurface/~4/AzWimEn_m7w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.slicksurface.com/blog/2008-12/changing-the-look-of-your-page-for-mobile-devices-and-printing/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.slicksurface.com/blog/2008-12/changing-the-look-of-your-page-for-mobile-devices-and-printing</feedburner:origLink></item>
		<item>
		<title>Use Apache’s .htaccess To Accomplish Cool And Useful Tasks</title>
		<link>http://feedproxy.google.com/~r/slicksurface/~3/8gvguuK9dHQ/use-apaches-htaccess-to-accomplish-cool-and-useful-tasks</link>
		<comments>http://www.slicksurface.com/blog/2008-11/use-apaches-htaccess-to-accomplish-cool-and-useful-tasks#comments</comments>
		<pubDate>Thu, 20 Nov 2008 21:09:29 +0000</pubDate>
		<dc:creator>Jay Harper</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Site Configuration]]></category>
		<category><![CDATA[CityTech ADV 4850]]></category>
		<category><![CDATA[mod_proxy]]></category>
		<category><![CDATA[mod_rewrite]]></category>

		<guid isPermaLink="false">http://www.slicksurface.com/blog/?p=294</guid>
		<description><![CDATA[One of the reasons why Apache is such a popular web server is because it's almost infinitely expandable and flexible. There are some incredibly powerful things you can do with Apache's config settings, and .htaccess is the most common way to modify those settings. First a little background. .htaccess is the name of the file. [...]]]></description>
				<content:encoded><![CDATA[<p>One of the reasons why Apache is such a popular web server is because it's almost infinitely expandable and flexible. There are some incredibly powerful things you can do with Apache's config settings, and .htaccess is the most common way to modify those settings.<span id="more-294"></span></p>
<p>First a little background. .htaccess is the name of the file. Yes, it starts with a dot which means on Unix based systems (like Linux and Apple's OS X) the file will be invisible. However, web authoring programs like Dreamweaver make it visible in their programs because they know it's power and importance.</p>
<p>You place the .htaccess file in a directory and the rules in that .htaccess file will affect that directory as well as all the subdirectories of that directory. It should be mentioned that .htaccess is a little inefficient. If you have access to your site's virtual host file, you can do pretty much the same things there more efficiently.</p>
<p>There are far too many things that are possible with .htaccess to discuss all of them here, so we'll just touch on some of the more common and useful things you can do.</p>
<p>One thing we should mention is that .htaccess is often used in combination with mod_rewrite. Apache is a modcular web application. There are probably 20-30 common modules that are used with Apache and mod_rewrite is one of them. mod_rewrite lets you do things to the URLs and based on the URLs. That may sound confusing, but it will make more sense in a moment. When you use mod_rewrite you need to have a line that reads:</p>
<p><code>RewriteEngine On</code></p>
<p>I'll be putting that in each of the examples, but when you use the code from this page you only need to have that line once in your .htaccess file - before the first mod_rewrite command.</p>
<p>The other thing I want to mention is that mod_rewrite is based on "regular expressions". If you really want to get into using mod_rewrite I suggest getting a book on regular expressions. You want a book that's concise and to the point since regular expresssions can get pretty complicated, but the basics are pretty straightforward.</p>
<p><em>Enforcing a canonical domain name</em></p>
<p>As you may know you can have often leave the www. out of a URL and the URL will work fine. The problem is that if you let people get to your site however they want and don't enforce either always having www or always not having www the search engines may think www and non-www are two different sites, since that's theoretically possible and was true in the early days of the world wide web. The problem with the search engines thinking you have two sites instead of one is that the authority of your site will be split and you'll have duplicate content issues. In fact the seach engine may even think one site is stealing content from the other site. The bottom line is that the search engines get confused and it's never good to get search engines confused.</p>
<p>The way to fix this with .htaccess is to have a statement that looks like this...</p>
<p><code>RewriteEngine On<br />
RewriteCond %{HTTP_HOST} !^www\.slicksurface\.com$<br />
RewriteRule ^(.*)$ http://www.slicksurface.com$1 [R=301,L]</code></p>
<p>Notice there is a RewriteCond line and a RewriteRule line. There will always be a RewriteRule line with mod_rewrite, and there can be zero or many RewriteCond lines. Think of RewriteCond as defining conditions that must be met before executing the rule.</p>
<p>You may know from scripting languages like Javascript that an ! means "not". Add to that the regular expression syntax ^ means "starts with" and $ means "ends with" and the first line is saying if the HTTP_HOST is NOT www.slicksurface.com. The backslashes are just there because the periods need to be escaped. And you should know (or at least guess) that HTTP_HOST is the <a href="http://www.slicksurface.com/blog/2008-09/php-101-using-apache-envirnoment-variables">Apache environment variable</a> that tells you the host name of the site.</p>
<p>So it's going to do something if the site name is now www.slicksurface.com - that 'something' is defined in the second line. (.*) is the way in regular expressions that you grab a bunch of characters. So ^(.*)$ is saying everything from the start to the end. But realize that RewriteRule acts on only the part of the URL that's in youru directory. So if you put the .htaccess file in http://www.slicksurface.com/blog/ Then it would be working on anything that came after that in the URL.</p>
<p>OK, so it's grabbed everything in the URL (not including the host name) and the second part of the second line uses $1 to tack that onto the end of http://www.slicksurface.com. The third part (the portion in brackets) tells Apache that you want to do a 301 (permanent) redirect (R=301), and that RewriteRule is the last line in what you're trying to do (L).</p>
<p>So try it out... Click on this link and see where you go...</p>
<p><a href="http://slicksurface.com/blog/" target="_blank">http://slicksurface.com/blog/</a></p>
<p>Notice it looks like www. gets added to the URL, which is basically true (in fact it wasn't "added" the user was quickly redirected to the URL with the www in it).</p>
<p><em>Page Moved Redirects</em></p>
<p>There are times when you want to move a page from one URL to another. You try to minimize doing these types of things, but sometimes they're just unavoidable. When you do need to move a page you want to put a redirect in place to let search engine spiders and people who may be following links from other sites know that the page has moved and be able to find what they're looking for.</p>
<p>A while back we migrated from using Blogger to using WordPress. This meant that all the URLs changed. We could write a general rule that covered many instances (see below), but some URLs didn't work with the rule. In those cases we had to have a simple RewriteRule to handle the rewrites. Here's an example of one of them...</p>
<p><code>RewriteEngine On<br />
RewriteRule ^2007/04/4d-backup-improves-creation-of-log.html$ http://www.slicksurface.com/blog/2007-04/4d-backup-improves-creation-of-log-files [NC,R=301,L]</code></p>
<p>So, if it's in a .htaccess file in the /blog/ directory, that will take the URL <a href="http://www.slicksurface.com/blog/2007/04/4d-backup-improves-creation-of-log.html" target="_blank">http://www.slicksurface.com/blog/2007/04/4d-backup-improves-creation-of-log.html</a> and redirects it to <a href="http://www.slicksurface.com/blog/2007-04/4d-backup-improves-creation-of-log-files" target="_blank">http://www.slicksurface.com/blog/2007-04/4d-backup-improves-creation-of-log-files</a> - notice that I'm doing a permanent 301 redirect. And lastly, the NC means that the rule is not case sensitive.</p>
<p>There are few ways to do redirects with Apache, but that's how you'd do it with mod_rewrite.</p>
<p><em>Rules To Redirect Pages Based On A Pattern</em></p>
<p>When we migrated from Blogger to WordPress the directory structure went from /blog/YYYY/MM/file.htm to /blog/YYYY-MM/file - that's a pretty easy pattern to migrate and we did so with the following mod_rewrite rule:</p>
<p><code>RewriteEngine On<br />
RewriteRule ^(\d{4})/(\d{2})/(.+)\.html$   http://www.slicksurface.com/blog/$1-$2/$3  [NC,R=301,L]</code></p>
<p>Let's look at this closely. While the regular expression code will probably be beyon your level of expertise - you can see that it's looking for something 4 and then something 2 and you'd be right if you guessed that's the 4 digit year followed by the 2 digit month. In other words (\d{4}) gets a 4 digit numeric string and (\d{2}) a 2 digit numeric string. (.+) is much like (.*) we saw above except (.+) requires that there be characters, where (.*) can work when there's nothing there. By putting those things in parentheses, we can pull them out in the URL we want to redirect to. They simply go in order $1, $2, $3...</p>
<p><em>Making The URL Different Than The File Name &amp; Location</em></p>
<p>Rewriting the URL is the reason mod_rewrite is named what it is. Let's say you have some files on disk but you don't want their folder structure and file names to be the actual URL. An example is <a href="http://www.slicksurface.com/medical-thesaurus/" target="_blank">the MeSH medical thesaurus</a> we put up here on slicksurface.com. It has over a hundred thousand files that needed to be organized in folders, but we didn't want those folders to be part of the URL, so we use mod_rewrite to accomplish our goal.</p>
<p>Let's take an example... We have the page on "Fungi" which has the following URL:</p>
<p><a href="http://www.slicksurface.com/medical-thesaurus/descriptor/D005658/fungi.htm" target="_blank">http://www.slicksurface.com/medical-thesaurus/descriptor/D005658/fungi.htm</a></p>
<p>But there's no actual document named fungi.htm in a folder named D005658. Instead the real file is at:</p>
<p><a rel="nofollow" href="http://www.slicksurface.com/medical-thesaurus/descriptor/8/D005658.htm" target="_blank">http://www.slicksurface.com/medical-thesaurus/descriptor/8/D005658.htm</a></p>
<p>What I did was randomize the files into 10 directories based on the last number in their ID. Then when I write files that refer to those files I add on the title of the page as a fake file name.</p>
<p>Here's the mod_rewrite syntax:</p>
<p><code>RewriteEngine On<br />
RewriteRule ^descriptor/D(\d\{5})(\d)/   descriptor/$2/D$1$2.htm [L]</code></p>
<p>So what that did was serve one file when another file was requested. If you notice the virtual file name isn't used at all, so the following URL would work just as well...</p>
<p><a rel="nofollow" href="http://www.slicksurface.com/medical-thesaurus/descriptor/D005658/foo.htm" target="_blank">http://www.slicksurface.com/medical-thesaurus/descriptor/D005658/foo.htm</a></p>
<p>Another thing you might notice is no $ was used - we just defined the beginning of the pattern and that was enough.</p>
<p><em>Having One Template Control Everything In A Directory</em></p>
<p>Another example similar to the one we just covered is having a single template control all the URLs for a directory. For example, let's say you have a file named index.php that takes a GET parameter of 'id'. The URL might look something like this if you were calling the template directly:</p>
<p>http://www.slicksurface.com/test/index.php?id=1234</p>
<p>But you don't want to have it look like that, you want the URLs to look like this:</p>
<p>http://www.slicksurface.com/test/1234.htm</p>
<p>All the numbered pages don't have to actually exist - all those URLs can be passed onto the template using something like the following:</p>
<p><code>RewriteEngine On<br />
RewriteRule ^(.+).htm index.php?id=$1</code></p>
<p>Using a strategy like that can be very powerful and let you have one PHP template that can be thousands of URLs that are more search engine friendly than index.php?id=1234. You can do something similar with text, but it's more complicated to handle things like spaces and special characters.</p>
<p><em>Serving Pages From Other Sites As URLs On Your Site</em></p>
<p>.htaccess can be used with more than mod_rewrite. Another use is with mod_proxy. mod_proxy pulls pages from other sites and can show them as pages on your site, though there are some issues.</p>
<p>Let's take the following page on Dan Wong's site - it's the home page for the advanced web site design course.</p>
<p><a href="http://www.dan-wong.com/advanced-web-design.htm" target="_blank">http://www.dan-wong.com/advanced-web-design.htm</a></p>
<p>Here's a mod_rewrite rule that has the P parameter specifying that it's a mod_proxy situation, not a redirect.</p>
<p><code>RewriteEngine On<br />
RewriteRule ^test/adv-3650$ http://www.dan-wong.com/advanced-web-design.htm [P,L]</code></p>
<p>With that you can see the content of the page at the following URL:</p>
<p><a rel="nofollow" href="http://www.slicksurface.com/test/adv-3650" target="_blank">http://www.slicksurface.com/test/adv-3650</a></p>
<p>But notice that the page doesn't look right. That's because it's not being served from the correct site, so all of the links to stylesheets and images are broken. If he had started all of the references with http://wwww.dan-wong.com/... then the page would actually look correct.</p>
<p>When this is useful is when you have an web application server that is responsible for some, but not all of the files on your website. In that case you can proxy the web application server, pehaps through a secure firewall, and because it's part of an overall system, where the web application server may actually think it is the entire site, the pages will render correctly.</p>
<p>You don't have to use mod_rewrite to use mod_proxy. Here is an example of a mod_proxy statement that you might find in an .htaccess file:</p>
<p><code>ProxyPass customer/ http://127.0.0.1:8080/customer/</code></p>
<p>That will pass all of the URLs from the customer directory onto a web application server that's responding to the 8080 port on the same machine as the web site.</p>
<p><em>Excluding Directories From Being Controlled by WordPress</em></p>
<p>WordPress controls everything in the directory it's installed in. If you want to have say a resources directory that WordPress doesn't control, or a robots.txt file that WordPress doesn't control, then you can use something like this:</p>
<p><code>RewriteEngine On<br />
RewriteCond %{REQUEST_URI} !^resources/<br />
RewriteCond %{REQUEST_URI} !^robots.txt<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteRule . index.php [L]</code></p>
<p>The bottom three lines are standard for WordPress, but the top two exclude the resources directory and the robots.txt file.</p>
<p><em>Making HTM Files Execute PHP</em></p>
<p>Sometimes you want to hide the fact that a php file is really a php file, or you just like your URLs to end with .htm rather than PHP. To make it so you can put PHP in .htm files you put the following in the .htaccess file:</p>
<p><code>AddType application/x-httpd-php .htm</code></p>
<p><em>Wrap Up</em></p>
<p>So there's a lot you can do with .htaccess files. Chances are if you're hitting a wall and need to do something special there's a way to do it with an htaccess file.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/slicksurface?a=8gvguuK9dHQ:_10Ao_9IeEE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=8gvguuK9dHQ:_10Ao_9IeEE:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=8gvguuK9dHQ:_10Ao_9IeEE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=8gvguuK9dHQ:_10Ao_9IeEE:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=8gvguuK9dHQ:_10Ao_9IeEE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=8gvguuK9dHQ:_10Ao_9IeEE:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=8gvguuK9dHQ:_10Ao_9IeEE:wF9xT3WuBAs"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=8gvguuK9dHQ:_10Ao_9IeEE:wF9xT3WuBAs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/slicksurface/~4/8gvguuK9dHQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.slicksurface.com/blog/2008-11/use-apaches-htaccess-to-accomplish-cool-and-useful-tasks/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.slicksurface.com/blog/2008-11/use-apaches-htaccess-to-accomplish-cool-and-useful-tasks</feedburner:origLink></item>
		<item>
		<title>How To Do An Outbound Link Script For Affiliate Links To Sponsors</title>
		<link>http://feedproxy.google.com/~r/slicksurface/~3/i4aXDuEHiGM/how-to-do-an-outbound-link-script-for-affiliate-links-to-sponsors</link>
		<comments>http://www.slicksurface.com/blog/2008-11/how-to-do-an-outbound-link-script-for-affiliate-links-to-sponsors#comments</comments>
		<pubDate>Thu, 13 Nov 2008 21:22:20 +0000</pubDate>
		<dc:creator>Jay Harper</dc:creator>
				<category><![CDATA[Advertising]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SEO/SEM]]></category>
		<category><![CDATA[CityTech ADV 4850]]></category>
		<category><![CDATA[PageRank]]></category>
		<category><![CDATA[Paid Links]]></category>

		<guid isPermaLink="false">http://www.slicksurface.com/blog/?p=282</guid>
		<description><![CDATA[Having an outbound link script is a good idea for many reason. You can quickly and easily change particular types of links throughout your site. You can control the flow of PageRank, and you can keep search engine spiders away from paid links that they don't want to see. This post goes into how to build an outbound link script using PHP.]]></description>
				<content:encoded><![CDATA[<p>In the last post I discussed <a href="http://www.slicksurface.com/blog/2008-11/how-to-do-rotating-banner-and-text-ads-with-php">how to do a script to randomly display banner ads</a> on a site. The next step is how to handle the clicks on those ads (or on text ads).</p>
<p>You might just think you should embed the links directly in the HTML, but that's often a bad idea. Let's say your sponsor runs a special promotion that uses a special promo link code. You may have the links all throughout your site in blog posts, banner ads, sidebar text ads, etc. There will be too many things to change to take advantage of the special promotion. Having all your outbound sponsor links go through a single script will fix that problem - change things in one place and all your links are changed.<span id="more-282"></span></p>
<p>The way this works is we want to pass into a script URL the ad number (or name) that you want to display. So your URL would look something like this:</p>
<p>http://www.domain.com/scripts/ad-links.php?adid=1234</p>
<p>So ads.php is the script we'll create, and adid is the ad ID for your outbound link.</p>
<p>Sometimes you have to enter other parameters into the ad URLs to meet sponsor guidelines, You can do that as well with a URL that looks something like this:</p>
<p>http://www.domain.com/scripts/ad-links.php?adid=1234&#038;param1=ABC&#038;param2=XYZ</p>
<p>So in that case the sponsor is asking for other information that may vary depending on the context of the ad, so there are two parameters that you can pass into the script which you can insert into the code displaying the banner ad - param1 and param2.</p>
<p>Now, before you start it's a good idea to think about what you want to do with search engine spiders. Search engine spiders don't want to see paid links and affiliate links to sponsors definitely fall into the "paid links" category. You have two options. One is to exclude them completely using robots.txt, the other is to let them crawl the links, but send them to a different URL than a real customer would go to - send them to a relevant page on one of your own sites.</p>
<p>So, let's say your link is to a company that sells pop corn. The best page to send the search engine spider to would be the tag page on your blog that has all the posts about the different types of pop corn offered by the company in question. If you don't have a page like that then you could send them to the page with all the posts about their company or a page with all the different pop corn reviews you might have. The point is, keep it relevant. If you keep it relevant the search engines shouldn't say you're cloaking. If you don't have a relevant page, then 302 them to the main page of your site. The 302 redirect doesn't pass page rank, so this should be a harmless way of keeping them away from paid links without them thinking your playing page rank sculpting games to deceive them.</p>
<p>Now, onto the script... Here's a brief version of the script:</p>
<p><code>&lt;?php<br />
if (stripos($_SERVER['HTTP_USER_AGENT'], 'googlebot') &gt; 0) { $spider = TRUE; }<br />
elseif (stripos($_SERVER['HTTP_USER_AGENT'], 'msnbot') &gt; 0) { $spider = TRUE; }<br />
elseif (stripos($_SERVER['HTTP_USER_AGENT'], 'teoma') &gt; 0) { $spider = TRUE; }<br />
elseif (stripos($_SERVER['HTTP_USER_AGENT'], 'slurp') &gt; 0) { $spider = TRUE; }<br />
else { $spider = FALSE; }<br />
/* Pop Corn Sponsor */<br />
if (($_GET['adid'] == 1) &amp;&amp; ($spider)) { header("Location:http://www.your-domain.com/tag/pop-corn-sponsor-posts",TRUE,301); }<br />
elseif ($_GET['adid'] == 1) { header("Location:http://join.pop-corn-sponsor.com/track/ODM4NzA1NzozMzoxNQ/",TRUE,302); }<br />
/* Pop Corn Maker Sponsor */<br />
elseif (($_GET['adid'] == 2) &amp;&amp; ($spider)) { header("Location:http://www.your-domain.com/</code><code>",TRUE,302); }<br />
elseif ($_GET['adid'] == 2) { header("Location:http://</code><code>join.pop-corn-machine-sponsor.com</code><code>/track/ODM4NzA1NzozMzoxNg/",TRUE,302); }<br />
else</code><code><br />
</code><code>header("HTTP/1.0 404 Not Found");<br />
</code><code>echo "&lt;html&gt;&lt;head&gt;&lt;title&gt;Link Error&lt;/title&gt;&lt;/head&gt;&lt;body&gt;Link Error&lt;br /&gt;".$_GET['lnk']."&lt;br /&gt;".$_SERVER['HTTP_USER_AGENT']."&lt;/body&gt;&lt;/html&gt;";<br />
?&gt;</code></p>
<p>You can see why we started with a discussion of search engine spiders - it's the first thing the script deals with - the first if statement tests to see if the request is coming from one of the 4 big search engine spiders. If so, it sets the $spider variable to a value of TRUE.</p>
<p>Then there's a if, elseif statment where we go through all the possible adid values. There are two cases for each value - one for what do do with a spider, and the other for what do do with regular users. The PHP header function is used to do 301 (permanent) and 302 (temporary) redirects. Notice that I always send people off to other sites with 302 redirects (so no PageRank is given to the sponsors site), and I also use 302 redirects when I don't have a good page on one of my sites to send spiders. 301 redirects are only used for relevant redirects for spiders so PageRank doesn't accumulate in the redirect script itself.</p>
<p>And lastly there's an else case for what to do if I don't find the adid. First I want to indicate that the link was not found with a 404 (page not found) response code. This makes sure the error will show up as an error in my analytics. Next, I want to tell the user what happened with some very simple HTML code.</p>
<p>So there you have it - an outbound link script that's easy to maintain and SEO friendly.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/slicksurface?a=i4aXDuEHiGM:8OXpIS5Y1gY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=i4aXDuEHiGM:8OXpIS5Y1gY:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=i4aXDuEHiGM:8OXpIS5Y1gY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=i4aXDuEHiGM:8OXpIS5Y1gY:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=i4aXDuEHiGM:8OXpIS5Y1gY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=i4aXDuEHiGM:8OXpIS5Y1gY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=i4aXDuEHiGM:8OXpIS5Y1gY:wF9xT3WuBAs"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=i4aXDuEHiGM:8OXpIS5Y1gY:wF9xT3WuBAs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/slicksurface/~4/i4aXDuEHiGM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.slicksurface.com/blog/2008-11/how-to-do-an-outbound-link-script-for-affiliate-links-to-sponsors/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.slicksurface.com/blog/2008-11/how-to-do-an-outbound-link-script-for-affiliate-links-to-sponsors</feedburner:origLink></item>
		<item>
		<title>How To Do Rotating Banner And Text Ads With PHP</title>
		<link>http://feedproxy.google.com/~r/slicksurface/~3/bl1OPo5MDnk/how-to-do-rotating-banner-and-text-ads-with-php</link>
		<comments>http://www.slicksurface.com/blog/2008-11/how-to-do-rotating-banner-and-text-ads-with-php#comments</comments>
		<pubDate>Thu, 13 Nov 2008 20:28:22 +0000</pubDate>
		<dc:creator>Jay Harper</dc:creator>
				<category><![CDATA[Advertising]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Banner Ads]]></category>
		<category><![CDATA[CityTech ADV 4850]]></category>

		<guid isPermaLink="false">http://www.slicksurface.com/blog/?p=272</guid>
		<description><![CDATA[Rotating banner ads are extremely useful and far more effective than static ads that people quickly ignore as "visual noise". This post shows you an easy way to write a script that can put random banner ads on your site without needing a database or complicated third party solution.]]></description>
				<content:encoded><![CDATA[<p>If you want to have content on your site that changes every time someone loads the page there are a number of possible solutions. Most typically these are ads - either textual or graphical "banner ads", but the same solution can be used for other random content.</p>
<p>There are ad packages/"scripts" out there which are decent, but you should choose them carefully since moving to anything else will be time consuming once you're fully set up (so make sure you really like the package and it's easy to maintain before investing too much energy in it). The other problem with ad packages is that they're almost always database driven and I've frequently seen problems where they don't redirect the person correctly. So check out sites that use the ad package to make sure it works in the real world.<span id="more-272"></span></p>
<p>There are two elements to handling ads - displaying the ad, and handling the click. This post will just address displaying the ad. I'll do another post on <a href="http://www.slicksurface.com/blog/2008-11/how-to-do-an-outbound-link-script-for-affiliate-links-to-sponsors">how you can handle the outbound link</a>. The advantages of what I'm going to show here are:</p>
<ul>
<li>It's something you write and maintain yourself - that means you can customize it as you see fit. It's not some scary black box you don't really understand.</li>
<li>It's not database driven - that means it will be more reliable. It also means it has limitations - if you've got a very large number of ad types (say over 1,000), you should be using a database driven solution.</li>
</ul>
<p>The script is just a big if elseif statement. We're going to add in two features to the idea of a random banner ads - 1) static ads on certain pages, 2) special parameters for certain ads.</p>
<p>Here's a brief version of the script:</p>
<p><code>&lt;?php<br />
$n = rand(1,2);<br />
if ($_SERVER['SCRIPT_NAME']=="/tags/rays-great-popcorn")<br />
{ ?&gt;<br />
</code><code>&lt;a href="http://www.your-domain.com/scripts/ad-links.php?adid=41" onclick="<a>_gaq.push(['_trackEvent', 'Rays Great Popcorn', 'Banner Ad Click To Sponsor', 'Bottom Banner - Table Pic with Popcorn', 0, false]);</a>" target="rgpc"&gt;&lt;img border="0" src="http://www.your-domain.com/resources/bnrs/rays-great-popcorn-600-200.jpg" alt="Ray's Great Popcorn" width="600" height="200"&gt;&lt;/a&gt;<br />
&lt;script type="text/javascript"&gt; _gaq.push(['_trackEvent', '<code><a>Rays Great Popcorn</a></code>', 'Banner Ad View', '<code><a>Bottom Banner - Table Pic with Popcorn</a></code>', 0, false]); &lt;/script&gt;<br />
<code>&lt;?php</code> </code><code>}<br />
elseif ($n==1)<br />
{<code> ?&gt;</code><br />
&lt;a href="http://www.your-domain.com/scripts/ad-links.php?adid=41" onclick="<code><a>_gaq.push(['_trackEvent', 'Rays Great Popcorn', 'Banner Ad Click To Sponsor', 'Bottom Banner - 2 Bowls of Popcorn', 0, false]);</a></code>" target="rgpc"&gt;&lt;img src="http://www.your-domain.com/resources/bnrs/rays-great-popcorn-600-125.jpg" alt="Ray's Great Popcorn" width="600" height="125"</code><code> border="0"</code><code>&gt;&lt;/a&gt;<br />
<code>&lt;script type="text/javascript"&gt; _gaq.push(['_trackEvent', '<code><a>Rays Great Popcorn</a></code>', 'Banner Ad View', '<code><code><a>Bottom Banner - 2 Bowls of Popcorn</a></code></code>', 0, false]); &lt;/script&gt;</code><br />
<code><code>&lt;?php</code> </code><code>}</code><br />
</code><code>elseif ($n==2)<br />
{<code><code> ?&gt;</code></code><br />
echo "&lt;a href="http://www.your-domain.com/scripts/ad-links.php?adid=42&amp;param1=&lt;?php echo $_GET['param1']; ?&gt;" onclick="<code><a>_gaq.push(['_trackEvent', 'Freds Great Popcorn', 'Banner Ad Click To Sponsor', 'Bottom Banner - Hottest Popcorn In Town', 0, false]);</a></code>" target="fgpc"&gt;&lt;img src="http://www.your-domain.com/resources/bnrs/freds-great-popcorn-600-125.jpg" alt="Fred's Great Popcorn" width="600" height="125"</code><code> border="0"</code><code>&gt;&lt;/a&gt;<br />
<code><code>&lt;script type="text/javascript"&gt; _gaq.push(['_trackEvent', 'Fred<code><a>s Great Popcorn</a></code>', 'Banner Ad View', '<code><code><a>Bottom Banner - Hottest Popcorn In Town</a></code></code>', 0, false]); &lt;/script&gt;</code></code><br />
<code><code>&lt;?php</code> </code><code>}</code><br />
</code><code>else{ }<br />
?&gt;</code></p>
<p>So let's go over what the script does... First, it sets a random number into the $n variable. Since we have two ads, it randomly picks a number between 1 and 2. Obviously as you add more cases for more ads, you'd up 2 to a bigger number.</p>
<p>Then it tests to see if we're on the page with the URL /tags/labels/rays-great-popcorn and if so, it displays a special ad that was made just for that page. That page doesn't get a random ad, it always gets that particular ad.</p>
<p>In the next two cases it checks the random number and randomly displays one of the two banner ads you have for your site (of course you'd have more than two).</p>
<p>In the second case it uses a special extra parameter in the outbound URL for the banner ad (param1). It uses PHP's $_GET array to pull the param1 element out of the array. The $_GET array holds all the query parameters you passed in the URL string when you did the include that called the script (we'll show that in a moment). That means that you have to pass all the parameters into the script that you might use in any of the random ads.</p>
<p>The way the script was written with multiple PHP statements. Alternatively you could write it with echo statements, but then you have to escape many of the characters. Generally multiple PHP statements makes for code which is much easier to understand and less prone to errors.</p>
<p>The HTML is pretty basic - an image with a link, so when you click on the image you follow the link. The one advanced aspect is the <a href="https://developers.google.com/analytics/devguides/collection/gajs/eventTrackerGuide" target="_blank">Google Analytics event tagging</a> that I've added in the link. That registers both the view of the banner ad as well as the outbound click as an event in Google Analytics. That will let you analyze what banner ads have the best click thru ratios, etc. That's a much longer topic and one I should turn into a blog post of it's own.</p>
<p>The best way to implement the script above is to save it in a separate PHP file and insert it into the page with a <a href="http://www.slicksurface.com/blog/2008-09/php-101-includes">PHP include</a>. So let's say we named the script banner-ads.php and we put it in an /includes/ directory at the root of our site. The include would look something like this:</p>
<p>&lt;?php include($_SERVER['DOCUMENT_ROOT']."/includes/banner-ads.php?param1=forum"); ?&gt;</p>
<p>So that pulls the file banner-ads.php and passes the value "forum" in as param1. That could be useful if you wanted to know the section of your site that was calling the banner ad - just change the value in each one of your templates (one value for the blog templates, one for the forum templates, etc.) But that could be achieved another way:</p>
<p>&lt;?php $param1="forum"; include($_SERVER['DOCUMENT_ROOT']."/includes/banner-ads.php"); ?&gt;</p>
<p>If you did that, then you wouldn't access the value with the $_GET array in the script, instead you'd just access the $param1 variable directly.</p>
<p>So there you have it - a simple way to implement random banner ads that's rock solid and easy to maintain by anyone with just a little bit of technical skills.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/slicksurface?a=bl1OPo5MDnk:Kv38Jy6hTg0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=bl1OPo5MDnk:Kv38Jy6hTg0:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=bl1OPo5MDnk:Kv38Jy6hTg0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=bl1OPo5MDnk:Kv38Jy6hTg0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=bl1OPo5MDnk:Kv38Jy6hTg0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=bl1OPo5MDnk:Kv38Jy6hTg0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=bl1OPo5MDnk:Kv38Jy6hTg0:wF9xT3WuBAs"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=bl1OPo5MDnk:Kv38Jy6hTg0:wF9xT3WuBAs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/slicksurface/~4/bl1OPo5MDnk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.slicksurface.com/blog/2008-11/how-to-do-rotating-banner-and-text-ads-with-php/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.slicksurface.com/blog/2008-11/how-to-do-rotating-banner-and-text-ads-with-php</feedburner:origLink></item>
		<item>
		<title>Dynamic Content With PHP Arrays (No Databases)</title>
		<link>http://feedproxy.google.com/~r/slicksurface/~3/fR5g9wIsVe4/dynamic-content-with-php-arrays-no-databases</link>
		<comments>http://www.slicksurface.com/blog/2008-11/dynamic-content-with-php-arrays-no-databases#comments</comments>
		<pubDate>Thu, 06 Nov 2008 19:52:35 +0000</pubDate>
		<dc:creator>Jay Harper</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[CityTech ADV 4850]]></category>

		<guid isPermaLink="false">http://www.slicksurface.com/blog/?p=274</guid>
		<description><![CDATA[You don't actually need to have a database to have some dynamic content on your site. You can use arrays instead. Let's say you want to randomly show 3 Star Wars DVD box covers from Amazon.com with links to the item on Amazon. To do that you'd need three things - 1) The title of [...]]]></description>
				<content:encoded><![CDATA[<p>You don't actually need to have a database to have some dynamic content on your site. You can use arrays instead. Let's say you want to randomly show 3 Star Wars DVD box covers from Amazon.com with links to the item on Amazon. To do that you'd need three things - 1) The title of the movie, 2) the URL of the box cover, and 3) the link to the item.</p>
<p>You define the values that you'll choose from in PHP arrays. To do that you do something like this...</p>
<p><code>&lt;?php<br />
$titles = array ("Star Wars - Episode I, The Phantom Menace", "Star Wars - Episode II, Attack of the Clones", "Star Wars - Episode III, Revenge of the Sith", "Star Wars Episode IV - A New Hope", "Star Wars Episode V - The Empire Strikes Back", "Star Wars Episode VI - Return of the Jedi", "Star Wars - Clone Wars, Vol. 1", "Star Wars - Clone Wars, Vol. 2");</code></p>
<p>$pageURLs = array("http://www.amazon.com/Star-Wars-Episode-Phantom-Widescreen/dp/B00003CX5P/ref=sr_1_4?ie=UTF8&amp;s=dvd&amp;qid=1225998531&amp;sr=1-4", "http://www.amazon.com/Star-Wars-Episode-Attack-Widescreen/dp/B00006HBUJ/ref=sr_1_7?ie=UTF8&amp;s=dvd&amp;qid=1225998531&amp;sr=1-7", "http://www.amazon.com/Star-Wars-Episode-Revenge-Widescreen/dp/B00005JLXH/ref=sr_1_6?ie=UTF8&#038;s=dvd&#038;qid=1225998531&#038;sr=1-6", "http://www.amazon.com/Star-Wars-Episode-IV-Widescreen/dp/B000FQJAIW/ref=sr_1_5?ie=UTF8&amp;s=dvd&amp;qid=1225998531&amp;sr=1-5", "http://www.amazon.com/Star-Wars-Episode-Versions-Widescreen/dp/B000FQJAJG/ref=sr_1_9?ie=UTF8&amp;s=dvd&amp;qid=1225998531&amp;sr=1-9", "http://www.amazon.com/Star-Wars-Episode-VI-Widescreen/dp/B000FQVX78/ref=sr_1_10?ie=UTF8&amp;s=dvd&amp;qid=1225998531&amp;sr=1-10", "http://www.amazon.com/Star-Wars-Clone-Vol-1/dp/B0006Z2LMO/ref=sr_1_12?ie=UTF8&amp;s=dvd&amp;qid=1225998531&amp;sr=1-12", "http://www.amazon.com/Star-Wars-Clone-Vol-2/dp/B000BCE8Q4/ref=sr_1_14?ie=UTF8&amp;s=dvd&amp;qid=1225999439&amp;sr=1-14");</p>
<p>$imgURLs = array ("http://ecx.images-amazon.com/images/I/51BR3RNVKZL._SL160_AA115_.jpg", "http://ecx.images-amazon.com/images/I/51BGV8AJ4RL._SL160_AA115_.jpg", "http://ecx.images-amazon.com/images/I/51RHXMVH9YL._SL160_AA115_.jpg", "http://ecx.images-amazon.com/images/I/517M4V93K0L._SL160_AA115_.jpg", "http://ecx.images-amazon.com/images/I/510GTNVNYYL._SL160_AA115_.jpg", "http://ecx.images-amazon.com/images/I/51CWJ6PC1KL._SL160_AA115_.jpg", "http://ecx.images-amazon.com/images/I/51A6GEB6SAL._SL160_AA115_.jpg", "http://ecx.images-amazon.com/images/I/51F7C82EDGL._SL160_AA115_.jpg");</p>
<p>$titleCount = count($titles);<br />
$element1 = rand(0, $titleCount-1);<br />
$element2 = rand(0, $titleCount-1);<br />
if ($element2==$element1) {$element2 = rand(0, $titleCount-1);}<br />
$element3 = rand(0, $titleCount-1);<br />
if ($element3==$element1) {$element3 = rand(0, $titleCount-1);}<br />
if ($element3==$element2) {$element3 = rand(0, $titleCount-1);}<br />
?&gt;</p>
<p>So you'll need something like that to initialize the arrays. Then you use them by displaying an image with a link to the page on Amazon.com. The code for the image and link would look something like this..</p>
<p><code>&lt;a href="&lt;?php echo $pageURLs[$element1]; ?&gt;" target="amazon"&gt;&lt;img src="&lt;?php echo $imgURLs[$element1]; ?&gt;" alt="&lt;?php echo $titles[$element1]; ?&gt;" title="&lt;?php echo $titles[$element1]; ?&gt;" /&gt;&lt;/a&gt;</code></p>
<p>So the basic syntax is a <a href="http://www.slicksurface.com/blog/2008-09/php-101-echo-the-command-that-inserts-text">PHP echo</a> that specifies the array and the value of the element of the array. $titles[$element1] means the $title array and the element of the array is the value found in the $element1 variable. If you had put $titles[1] that would be element 1 of the array (which is actually the second element in the array since elements start their counting at zero, not 1).</p>
<p>So let's see it in action...</p>
<p><a href="http://www.amazon.com/Star-Wars-Clone-Vol-2/dp/B000BCE8Q4/ref=sr_1_14?ie=UTF8&#038;s=dvd&#038;qid=1225999439&#038;sr=1-14" target="amazon"><img src="http://ecx.images-amazon.com/images/I/51F7C82EDGL._SL160_AA115_.jpg" alt="Star Wars - Clone Wars, Vol. 2" title="Star Wars - Clone Wars, Vol. 2" /></a>&nbsp;&nbsp;&nbsp;<a href="http://www.amazon.com/Star-Wars-Episode-Phantom-Widescreen/dp/B00003CX5P/ref=sr_1_4?ie=UTF8&#038;s=dvd&#038;qid=1225998531&#038;sr=1-4" target="amazon"><img src="http://ecx.images-amazon.com/images/I/51BR3RNVKZL._SL160_AA115_.jpg" alt="Star Wars - Episode I, The Phantom Menace" title="Star Wars - Episode I, The Phantom Menace" /></a>&nbsp;&nbsp;&nbsp;<a href="http://www.amazon.com/Star-Wars-Clone-Vol-1/dp/B0006Z2LMO/ref=sr_1_12?ie=UTF8&#038;s=dvd&#038;qid=1225998531&#038;sr=1-12" target="amazon"><img src="http://ecx.images-amazon.com/images/I/51A6GEB6SAL._SL160_AA115_.jpg" alt="Star Wars - Clone Wars, Vol. 1" title="Star Wars - Clone Wars, Vol. 1" /></a></p>
<p>Now, if you take it a step further, the definition of the arrays can happen in an external file and put into the page with a <a href="http://www.slicksurface.com/blog/2008-09/php-101-includes">PHP include</a>. That file can be written with a database application. Which means you could have a site with dynamic content running without any databases on the web server itself. </p>
<p>There are many uses for this type of thing - imagine a "picture of the day" script, or a banner ad rotating script. The options are pretty wide ranging.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/slicksurface?a=fR5g9wIsVe4:j5JsEryL7SY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=fR5g9wIsVe4:j5JsEryL7SY:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/slicksurface?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=fR5g9wIsVe4:j5JsEryL7SY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=fR5g9wIsVe4:j5JsEryL7SY:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=fR5g9wIsVe4:j5JsEryL7SY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=fR5g9wIsVe4:j5JsEryL7SY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/slicksurface?a=fR5g9wIsVe4:j5JsEryL7SY:wF9xT3WuBAs"><img src="http://feeds.feedburner.com/~ff/slicksurface?i=fR5g9wIsVe4:j5JsEryL7SY:wF9xT3WuBAs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/slicksurface/~4/fR5g9wIsVe4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.slicksurface.com/blog/2008-11/dynamic-content-with-php-arrays-no-databases/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.slicksurface.com/blog/2008-11/dynamic-content-with-php-arrays-no-databases</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 0.266 seconds. --><!-- Cached page generated by WP-Super-Cache on 2013-05-21 15:42:52 --><!-- Compression = gzip -->
