Make Your Site Mobile-Friendly in Two Minutes
After checking out B. Adam Howell’s excellent IYHY.com site a couple of weeks ago, I thought it might be a good idea to write a little tutorial about how to make your entire site more mobile-friendly without even touching your pages. You may think that since you write valid code and separate structure from presentation at all times, your site already works great on mobile devices. You may also think bad things don’t happen to good people. In both cases, you’d be wrong.
The fact of the matter is that the state of HTML rendering in the wireless world is all over the map right now. Some browsers, like Pocket Internet Explorer, are actually pretty good at parsing through standard web pages. Others can scarcely handle layout rules at all. And still worse are the mobile browsers that load all CSS and javascript files, attempt to use them, and screw up the experience even more in the process.
What’s really needed until HTML/CSS/JS support is improved in mobile devices is a little server-side filtering. By pulling out everything a mobile device can possibly choke on before it even gets to the mobile device, we can create a mobile version of our site which is not only viewable on more devices but is much quicker to download as well.
And you know what? The mobile version of your site is probably going to be much easier on screenreaders too.
Four easy steps
Outlined below are the four steps to get this done in a matter of minutes, provided you are in an Apache environment and can run PHP. If you’re not, these steps can easily be adaptable to other technologies.
Step 1: Set up a domain mirror
If your site lives at www.myawesomeblog.com, you’re going to want to set up a subdomain at mobile.myawesomeblog.com. How you accomplish this is usually pretty straightforward but differs depending on your host. I use Dreamhost and from their control panel, I can add subdomains effortlessly until I pass out from excitement. You want to set up your subdomain as a “mirror” of your main site, meaning the subdomain is really just pointing to your existing site.
Step 2: Create global_prepend file
The next thing we’re going to do is a create a PHP file which will be automatically prepended to every page of our site. Call this file something like "global_prepend.php" and throw it at the root of your server:
This code uses a PHP function called ob_start() to read in your entire HTML source, run some rules on it, and then send the output to users’ web browsers… all in real time. The first "if" statement simply checks to see if the user is coming from our special “mobile” URL, and if so, runs seven replace statements on the code. Here’s what each line does:
- Changes all URLs to “mobile”-ized URLs.
- Strips all linefeeds, carriage returns, and tabs.
- Trims multiple spaces down to one (HTML doesn’t recognize more than one space in a row).
- Changes any anchored images with alt text to plain text anchors.
- Strips all stylesheets, images, inline styles, scripts, and comments (including RDF).
- Tells search engine robots not to index or crawl the mobile version of the site so as to not create duplicate listings.
Step 3: Create global_append file
Next, we need to create a tiny PHP file which will automatically get added to the end of every file on our site. This is the code that actually outputs the page to the browser. So the flow is like so: Suck code into buffer, siphon fat away, spit contents of buffer into browser.
The code for the global_append file is below. Call it something like "global_append.php" and throw it at the root of your server:
Step 4: Enable prepends and appends using .htaccess
If you don’t already have an .htaccess file at the root of your server, open up a new text file and add these lines to it:
php_value auto_prepend_file /localfilepath/global_prepend.php
php_value auto_append_file /localfilepath/global_append.php
Then save it to the root of your server with the filename ".htaccess". If you already have an .htaccess file, just add the above lines to it.
* Important Note: If you copy these two lines from your web browser, you might need to delete the carriage return and make your own. Sometimes a browser’s carriage return will cause your .htaccess file to fail (you’ll know immediately if it has failed because your site won’t come up).
Assuming your subdomain is live, you should now be able to hit your site in a web browser using the special mobile URL and see a nice, compact, imageless, styleless, scriptless version of your site. Voila!
Here is what Mike Industries Mobile looks like.
A look at the results
Let’s look at some before and after shots of Mike Industries and a few other notable sites when taken “under the knife” (screenshots are from a Treo 600):
Mike Industries |
|
|---|---|
![]() Size: 72k Time to render: 33 seconds |
![]() Size: 26.1k Time to render: 5 seconds |
Mezzoblue |
|
![]() Size: 31k Time to render: 22 seconds |
![]() Size: 8.3k Time to render: 5 seconds |
Stopdesign |
|
![]() Size: 68k Time to render: 28 seconds |
![]() Size: 15.7k Time to render: 5 seconds |
Zeldman |
|
![]() Size: 29.8k Time to render: 17 seconds |
![]() Size: 25.3k Time to render: 13 seconds |
Shaun Inman |
|
![]() Size: 101k Time to render: 39 seconds |
![]() Size: 18.9k Time to render: 5 seconds |
Joe Clark |
|
![]() Size: 97.1k Time to render: 23 seconds |
![]() Size: 58k Time to render: 7 seconds |
Gizmodo |
|
![]() Size: 177.6k Time to render: 62 seconds |
![]() Size: 46.2k Time to render: 7 seconds |
The figures above illustrate both speed and compatibility improvements in all cases and this is with image loading turned off on my device. Flip image rendering back to its default setting of “on” and the improvements are staggering.
It’s important to note that the tests above do not point to any coding problems or inefficiencies on the part of the site authors (except for mine, which is just a big pile of crap). The fact that sites above average about 30 seconds to even begin rendering is more a function of the speed of cellular networks and the inability of some mobile devices to efficiently display content. Since we can’t change either of those things, we do what we can in the meantime, and that’s what this is all about.
Notes and thoughts moving forward
- I openly invite anyone reading this article to suggest improvements to my replace statements in the
ob_start()code. The Wolf has spit milk through his nose checking my regular expressions in the past, but with his help and the help of the best tutorial in the world, the regexes are pretty tight now. If you have any modifications or additions, post them in the comments and I’ll merge them in if appropriate. - Using
ob_start()requires PHP to parse through your pages, thus creating additional server load. Dreamhost lets me test CPU load and I don’t notice any problems or performance degradation, but if you’re hosting on a Commodore 64 or in an extremely high traffic environment, just make sure everything is still humming along after you’re all set up. - In order to use auto prepending and auto appending, you must be running PHP as a standard Apache module and not “as cgi”. If need be, you can run PHP as Apache sometimes and CGI other times by using your .htaccess file to specify rules.
- I specifically left out much mention of accessibility in this article because each site and each screenreader are different, but you can begin to see how radically we can simplify pages on the server-side to improve such things. In the world of accessibility, simpler is almost always better. It’s the reason why Joe Clark’s name is only two syllables.
- Finally, there are all sorts of ways to expose your “lite” version to users. I
will probably simply add a “lite” themehave added a “Mobile Version” link to my selection of themes in the sidebar, but you could just as easily write a snippet of javascript to automatically send people with screen resolutions of less than 640×480 or certain known wireless user agents to your lite site. - Note to Dreamhost users: Dreamhost runs PHP as CGI by default. To switch it over so it runs as an Apache module, just go to “Domains > Manage > Edit” in the control panel. Then, uncheck the “run PHP as CGI” box. Also, if you have HTML pages on your site that aren’t PHP, you can force them through the PHP interpreter by adding this line to your .htaccess file:
AddType application/x-httpd-php .html .htm















…and accessiblity on the server side begins (returns?). ;) I like this method very much - it makes perfect sense to me.
Minimal overhead and maximum result.
Very good. I’ll implement this at once.
Very nice. Although this assumes the content/content strategy of the site in questions is appropriate for a mobile device.
I’d argue that in many cases (and in addition to the rendering) the content itself may need to be tweaked for mobile consumption. But I suppose that’s another conversation altogether.
Excellent tutorial, Mike. The real problem has been the mobile browsers, on the TREO for example, that attempts to load the js and the css and render them as if its a big-boy browser. Your method solves that.
It would also be nice, if it can be systemically detected, to replace all form objects that have an “onchange” submit, and dynamically add a “submit” button. I found this out hard way while testing several of my sites.
Great work.
For full mobile support, it would be a better idea to use WML, HDML or XHTML mobile profile, instead of a two-minute hack. But, very nice.
Since Unobtrusive Javascript (or progressive enhancement, pick the one you prefer) practices forbid that kind of things (in favor of removing the submit button and adding an onchange handler at runtime) and Mike’s script removes the scripts calls, this shouldn’t be too much of a problem on a well coded website.
Or would it?
It would also be nice if any of those were supported consistently across devices.
I shall like to do this here at K-State. As we don’t do PHP, it will have to be re-done in Java, but that shouldn’t be an issue. Great technique!
1997 all over again! Can’t we just skip over the next 8 years and just get to the good stuff? ;-)
Amazing! Completely in-depth. Just the resource I’ve been looking for.
I was thinking about something: in the current state, you need subdomains for the technique to work, but not everyone has access to subdomains, especially on some free or lowly princed hosts (students and the like can’t always affort a “true” hosting solution).
I guess the solution would kinda look like that:
First of all let’s change the “if” check to
then add a rewriting entry for to map /mobile to ?mobile (no need for a value) (or modify existing rules accordingly), and finally change
str_replace('http://domain.suffix', 'http://mobile.domain.suffix', $buffer);to
str_replace('http://domain.suffix', 'http://domain.suffix/mobile', $buffer);would anyone care to test?
It would probably be possible to get rid of the rewriting need through some work with regular expressions powered replaces.
Anyway, truely great and inventive solution Mike, kudos to you
Great tutorial Mike.
This is a nice solution to the problem of cross publishing to the mobile devices. A couple of quick notes to add to the discussion.
1. Tom is right, it is better to make a WML or XHTML-MP version of your site, getting the target size of your pages down to less then 20k per page. But to Kevin’s point, most modern mobile devices support WAP 2.0 and if you write good XHTML-MP content you should be good on most devices.
If you are worried about supporting the maximum amount of devices, WML is still the way to go.
2. Most carrier styleguides call for a maximum of 10-12 links per page (here is a link to Cingular’s) For the maximum consistency across multiple devices, it’s worthwhile to checkout a few mobile styleguides.
3. The Treo 650 has a 312Mhz processor, significantly more powerful than most mobile devices, which will impact your rendering time.
4. PHP has spotty support on a lot of phones. For example a lot of Samsung phones will choke on PHP.
Sad, but true for both mobile browsers and web browsers…
Mike: Well, you certainly beat me to the punch, didn’t you? Very nice. I thought the idea was great when you first suggested it and now seeing it in action I’m still just as impressed.
Now, the only question is, should I make a mobile.iyhy.com version of IYHY? ;)
Brian wrote:
Brian, could you elaborate? As PHP is completely server-side, do you mean that Samsung phones choke on URLs with query string variables? Or do you mean that Samsung phones don’t like the .php filename extension? Or is it a content-type header that’s returned by the webserver that Samsung phones don’t like? Any of those things can be overcome, and I can’t see how a browser can tell if a webserver is using PHP behind the scenes to handle requests, or if the webserver is pulling static HTML files.
</tangent>
Mike, here’s a thought worth considering if it doesn’t stray too far from the topic at hand; one I had to face while preparing my presentation: I’m all for hacks like these, as they’re shamelessly easy to implement.
But are we ignoring the content-, context-, and feature-specific needs of mobile users? If I can afford only a few minutes to produce a mobilized version of my site, what’s presented here is excellent. But should it be used across the board, or should I first understand how/what/when mobile users will access my site, and then address the display issues once I understand that?
Regardless, resources like these can only help push us in the right direction regarding mobile web design. (And feel free to kill this comment if it’s too far off topic.)
This is great stuff. This home mobile accessibility thing is really picking up pace. nice
Kevin and Cameron: Yes, I feel the same way about content for mobile devices as I do about content for the completely blind — without specifically crafting the experience for them, you’re not really optimizing their experience to the fullest. That said, however, unless you have the time and desire to do that, this two-minute solution gets you decently close to where you need to be.
Tom: WML, HDML, and and the like will work on some devices but not all. Simple HTML is the same way. Depending on your needs, you could easily tweak the regular expressions to spit out whatever language you’d like, as long as it’s a tag-based SGML derivative.
Masklinn: Yep, doing this with cookies instead is a great method if you can’t set up subdomains. I originally thought about doing it with cookies anyway, but I just like having a special mobile URL I guess. Thanks for posting that code.
Brian: Thanks… good info. With regards to mobile styleguides, however, I’m not real big on them. Phones change so quickly that the spec someone wrote last year is scarcely relevant anymore. The only thing I know for sure in the mobile world is that the simpler you make things, the more devices will be able to display it and that’s really all this method does: strip things down to their bare bones. Also, to echo another commenter, what is the issue with PHP? PHP is server-side and no mobile device could possibly even know PHP was running… unless I’m missing something.
B. Adam: Yes, it’s amazing how much work you can get done on your blog when you quit your job!
Mike, obviously, not mobile browsers support them. I agree. But for a bit more full and better support, it would be nice if we started with something that was designed for Mobile devices. That will also provide a little help to standardize all the mobile browsers in the long run.
I also disagree on using PHP regex to spit out to another language. That means you are doing more work than necessary. PHP was not designed to be a transformer for different markup languages originating from XML. Always starting from XML and using XSLT, XPath or any for-XML method to transforming is faster and a better idea.
Tom: I totally agree. Ideally, your templates will pull the same data from your database and spit it out in whatever language you need. In a best-case scenario, everything happens at the template level. XML with XSLT may be the best solution for the future as well.
My solution in this article is more of a “retrofit” solution. If you don’t have the time or desire to do what’s mentioned above, this gets you to a decent and practical place… in about two minutes.
You are right Mike. It is indeed a good two minute hack. Obviously, this hack would be ideal for majority of the readers and web developers out there. It would be too much for them to sit around and have a truly accessible site. I certainly understand what you’ve done, and appreciate it. :)
Mike -
Cool tutorial, but I have one question. All the sites you give examples of are blogs. Have you tested this out on any corporate type sites which aren’t blogs or designed completely with CSS?
Looks interesting Mike, but what I really want to know about is that first picture in the article and that great powder blue suit and tie ;-)
…or you could implement XHTML, Web Standards symantic code and a stylesheet with media=”handheld” declared…no?
My own site and those of my clients looks pretty much like your ‘after’ screen grabs on small devices Mike and I’ve never had to resort to any server side hacks despite tesing on a wide range of different handheld platforms. Opera for small devices or ‘Dorris’ are pretty good at rendering XHTML pages I find as well.
Don’t get me wrong - your example above is a nice idea for those who are not on board the Web Standards movement yet and need a quick fix but I do feel that ultimately it’s just a lazy shortcut instead of bitting the bullet and forging ahead by implementing projects with Web Standards in mind.
The whole idea behind Web Standards is that it sets a design/mark-up standard by which we should all [by now] be working to. After all, they are designed so that Web content is accessible and available for display on a wide range of devices that’s the whole purpose.
Both the Web design community and the manufacturers (espec) of Web enabled devices need to wholeheartedly embrace the concept and actualities of modern web page building instead of looking for the quick fix shortcuts and muddy workarounds - currently we are still in that transitional phase between the old tag soup way and the new cleaner, clearer global standard - if we adopt work arounds and short term hacks, surely we all might as well pack up and go home?
Adam,
Support for media=”handheld” is very very spotty - particularly in my testing on Palm’s web browsers. Beware.
Remember too - that maybe the *newest* browser supports some feature but most mobile users are stuck with whatever browser shipped with their handheld - it is very hard to upgrade to newer browsers. Almost every one I see requires a certain OS revision level or hardware requirement. Another gotcha might be that the mobile device are managed by an internal IT dept. and they’ve only certified browser X because they don’t have the money to train their staff on anything else.
Finally, as stated above… this is a good two minute hack. The CEO came downstairs and said “I tried our company site on my new widgetdoohickey and it crashed the device.” In two minutes you could have this fixed so that you could actually spend the time looking into doing it the right way for your business. That makes a *whole* lotta sense to me.
(And I’ve seen CSS, apache redirects, and server side coding crash Palm devices. web browser 2.0 and pro in particular can get all crashy crashy. It’d be nice if Palm provided *way* better testing environments to web devs.)
Shawn
Not using cookies here, using GET variables, but I guess it’s a typo thingie on your part.
AFAIK the code output by his rewriting script is semantic code, it’s pure HTML/XHTML (whatever the modified website uses), the only modified things in the (X)HTML source are the links which are mobilified… and some lightification of the code (stripping of whitespaces and newlines and such) to reduce the burned bandwidth.
The issue with @media handheld is that I think some devices don’t use it and always try to use @media screen.
Unstyled content (which is what is fed to the device by this snippet of code) always is a good base anyway.
I don’t really get your ’standard’ issue here, in fact, since Mike’s snippet only output 100% (X)HTML standard compliant and purely semantical code if the source page complies to the standards… he’s not creating a new page in a new language, he’s just getting rid of presentational and behavioral informations to bare the structural markup to the user agent… and it’s not even like he was creating a new version of the site, duplicating content and updating efforts here…
And you can see how long it has been since I left comment on a weblog… I just put my last name after it like it was an email. Shoot me now.
Tom, I don’t know if it’s that it would be “too much” for the majority of us to “sit around and have a truly accessible site”, but what’s particularly good about Mike’s approach from my point of view is that it can be easily applied.
The more of this work I do the more I am thinking accessibility from the ground up (XML/XSLT as you describe) but for existing projects, it’s great to have a quick fix like this that I can apply to stop the gap until I can rewrite code from the ground up.
…purely semantical code if the source page complies to the standards…
Sure….and if they are not…?
My concern, is that a designer who is still trundling along using tables and spacer gifs comes and see’s this here quick fix Mike has kindly put up on how to offer a mobile version of his tag soup for little effort - a quick fix bandaid if you will. It means he/she is not pushed to adopt current Standards to improve their game and ultimately the end product for the greater good, it’s just a quick ‘Get out of Jail’ card no? - maybe I’m wrong - Shawns CEO example makes perfect sense to me and can see how in those kind of situations it would be a Godsend to an inhouse Web Admin.
Don’t get me wrong it’s a great idea and a clever solution - I suppose in an ideal world we would access web content and the device being used would not only be complient with current standards it would also be able to determine, via the mark up rather than the server, how to display said content - like I said we are still in that transitional phase - double jeopardy I guess :o\
At the end of the day guys, this is still a nice quick fix. Not a catch-all, mind you, but an option worth considering.
Adam: Just a heads up, on a Treo 600 your site’s unreadable because half of your content is on the screen and the other half’s not.
So, if I wanted to actually read what you and your design firm were selling, I’d have to use Mike’s solution, or something like IYHY, in order to do it quickly and easily.
Just, you know, a little FYI.
Snarkiness aside, Adam, almost every mobile device does the web differently and hacks like this are, for the moment, required unless you want to spend literally days troubleshooting every device you can get your hands on.
Like my Treo 600, which can’t conveniently view your site without Mike’s hack or a site like IYHY. Oh, wait, did I already mention that?
Mike -
Do you currently have this feature enabled on your site? Pulling it up just now on my Treo 650 gives me the exact same GUI layout that I’d have on a “traditional” browser - not the stripped down version you indicate in your screenshots.
Adam: Yeah, as others have pointed out, you are missing the point here. Also, the assertion that sites like mine and the other several that I list in the examples are “tag soup” shows a clear lack of effort on your part to even understand what we’re talking about here. My site isn’t tag soup. Mezzoblue, Stopdesign, Zeldman, and Inman aren’t tag soup either. And in fact, the method discussed in this article actually works much better on standards-conscious sites than it does on tag soup sites. The better organized your code is, the better this method will work.
I also echo B. Adam’s comments that your site is completely unreadable on my own mobile device and probably many others as well. You fall squarely into the category I spoke of in the very first paragraph of the article:
Masklinn: Yep, HTTP GET requests, no cookies. My bad. My initial thought was cookies, but even cookie support in devices is spotty.
Mark: Are you pulling it up at “mobile.mikeindustries.com/blog/” ? I don’t have any automatic detection in there (yet) to try and catch you at the normal address.
Mike: - I no way inferred that your site was tag soup anywhere in my posts!!! - if you re-read my comments, I am referring not to obvious people like yourself who are coding semantically but rather to those out there that maybe would see this as a quick fix for possible bad code and yes it’s obvious that the hack would work a lot better on semantic code - that’s a given.
Think you have mis-interpreted my comments far too personally I am really genuinely sorry if you found offence at my feedback, it was not intentional - it’s a great hack okay! kudos - really!
B. Adam: - Thanks for the heads up - shame you felt the need to put it across in such a triumphalistic manner - I really wish I hadn’t bothered you lads - sorry - unfortunately some peeps seem to have missed the point I was trying to make [badly apparently] that I’ve not had a problem with devices I’ve tested - but it seems not all eh B. Adams
Have fun…
Adam: The reason your comments came across that way is that you are basically saying “If you code your sites with web standards in mind, your sites will work optimally on mobile devices”. This is simply not true, and is a main point of this article in fact. Furthermore, you went so far as to mention your own site as an example of this theory and all B. Adam, myself, and others are doing is calling you on that. Your site doesn’t work optimally on mobile devices… and it has nothing to do with the quality of your code. That’s what this little trick helps with.
And, come on, I said “snarkiness aside”. The snarkiness — all of it — had been set aside! The comment was 100% snark-free from then on.
Snark-lite. Reduced snark. 1/2 the snark of leading snarks.
Sheesh ;)
Ah this is an excellent little hack to accomplish a desired effect until browser standards become more upto date
In the global_prepend.php code, what is this for: <script src=”/mint/mint.js.php” type=”text/javascript” language=”javascript”></script>
And also, the script changes all urls to a mobile one, right? But I use relative urls on my site, so it won’t work.
Could you please explain the “mirroring” the subdomain? I have it set up but I don’t understand the process of having it point to the existing site. Thanks.
qwerty: Oooops, that Mint line shouldn’t have been in there. It’s removed now. With regard to relative URLs, they are fine. Since your visitor will already be at the mobile subdomain when they click any URLs, they will continue to be at that subdomain if they click a relative URL.
Tyler: Mirroring is basically just a setting on the server which says “point mobile.myawesomeblog.com to the same place as http://www.myawesomeblog.com“. It’s a setting that is generally available in the control panel of whatever your ISP is. Basically, it creates a DNS entry for “mobile.” which points to “www.”.
If you’re not using Dreamhost, the whole “mirroring” thing will probably confuse you (just as Mike has already said in the original post). I have not seen this feature anywhere else called as such.
If I was with some other hosting company besides Dreamhost (luckily, I am not), then I would write to support asking them how to accomplish this task, explaining it exactly like Mike did above (in plain english).
Great solution btw Mike, although a little Dreamhost centric at the moment.
Oh yeah, Tyler Durden? Is that your *real* name, because if that was my name I would be freaked out (Fight Club, for the uninitiated).
Justin: Is the ability to set up subdomains that point to your site root really that rare? I mean, I think I can even do it at the registrar level (GoDaddy) if I need to. Additionally, many hosts like Media Temple automatically point every subdomain to your root. For instance:
shreddedwheat.shauninman.com goes to Shaun’s root automatically.
I do agree with you that some of the lamer ISPs probably don’t let you do subdomains, but it seems pretty common, no?
Perhaps I misspoke. I know it is really easy to do with Apache and is probably common with all Apache-based solutions. Finding it on Dreamhost was the first time I’d seen it, maybe because it’s usually more hidden or maybe because the wording is different than other (more orthodox) hosting companies.
For the cost, Dreamhost lets you do really amazing things that I never thought I could do for $7.95 a month.
Doing subdomain aliasing at the registrar level is different though, because that would usually just redirect to your primary domain whereas a mirror on the server will actually function identical to your primary domain.
Yeah, I’m kinda having trouble with this mirror thing.
In cpanel, is there a way to do it? What about .htaccess? If so, what is the code I need?
Thanks.
Can’t do it with .htaccess. Why not just email your hosting company’s support staff, you know: support@hostingcompany.com
It’s always worked for me.
It is possible to fake sub-domains with mod_rewrite (in your .htaccess file). Not the best solution in the world, but it’ll work.
Example:
RewriteEngine on
# Ignore [url]www.yourdomain.com[/url]
RewriteCond %{HTTP_HOST} !^www\.yourdomain\.com [NC]
# Treat these request like a subdomain
RewriteCond %{HTTP_HOST} ^([a-z0-9-]+)\.yourdomain\.com$ [NC]
# Make sure that a directory matching the name of the subdomain exist.
RewriteCond %{DOCUMENT_ROOT}/%1 -d
# Tweak the URI to make it match the requested hostname and pass the result on to the next rewrite rule
RewriteRule ^(.+) %{HTTP_HOST}/$1 [C]
# Translate subdomain.yourdomain.com/sample to yourdomain.com/subdomain/sample
RewriteRule ^([a-z0-9-]+)\.yourdomain\.com/?(.*)$ [url]http://yourdomain.com/[/url]$1/$2 [L]
Mike, a quick question that has nothing to do with your current entry.
How do you set up your comments so that whenever you comment, you have a different looking comment body from the rest of the comments. It’s easy to see that in your CSS you use class=”lightcomment mike”… but I still can’t figure out how you doing it. I am sure you’ve been asked this before, but if you could shed some light on what you’re doing here I would greatly appreciate it.
Pete > Since he’s the blogger, he probably has some kind of logging in the blogging software which causes his comments to get the right classes automagically.
It’s a quite common thing, to distinguish the author(s) from the visitors/fakes. You can check it at Malarkey’s blog too, logged in users get to set a little flag on their comments and the arrow at the left is colorized (black for visitors, blue of Ian Lloyd and red for Malarkey)
The software just needs to check if you’re logged in (by checking $_COOKIE for example) and tag the comment appropriately at posting, the tag is then converted to classes at display time.
Late to the party, but I must say this is a nice, quick and convenient little solution to some of the problems we face with mobile web-users.
It’s no end-all-be-all solution, but it doesn’t have to be. Just the fact that it vastly speeds up the experience for said users makes it worthwhile, especially given its insane ease of implementation.
Good job, Mike. Very well-done!
Of the unlimited gayness available on my personal Weblog, you would of course screen-grab a quotation from Fran Liebowitz.
En tout cas, I already have a handheld stylesheet. So.
Or, more correctly, an handheld stylesheet.
Joe: Ha! True that a handheld stylesheet works well when it’s recognized, but it often isn’t. Also, CSS issues aside, the server-side solution shrinks your HTML quite a bit by removing the white space and the RDF stuff.
Also, I believe “a handheld” is actually the correct usage. When deciding between “a” and “an”, you go by the sound. If the following word begins with a vowel sound, you use “an”. So unless you pronounced it “andheld”, it’s “a handheld”. This is why “historical” can go both ways. “An historical” sounds like more “An istorical” when some people say it.
Somebody correct me if I’m wrong.
I’ve always just gone by how it sounds. If that’s because the word following an ‘a’ doesn’t have a consonant then so be it.
Hey, I just specify “media!=handheld” on my stylesheet, that works for me and my Pocket PC. (that’s a joke).
Mike, you’re correct. The choice between “a” and “an” is decided by the sound that follows it. An hour, a human being.
Historical should still be pronounced HIStorical and not “istorical” though, no matter how many people (wrongly) do the latter.
I don’t think you can argue pronunciation Faruk, that is too culture dependent. If you want to get technical, look at the dictionary for “proper” pronunciation.
HIStorical sounds too masculine for my liking anyway.
Hi,
I tried to follow your (simple) four-steps with no success.
I still see the regular site, instead of ‘text-version.’
Like you, I’m DreamHost’ subscriber. Actually recommended by you…
Q: Does this sound correct? (.htaccess file)
php_value auto_prepend_file /home/arthaus/arthauscommunications.com/global_prepend.php
Thankx in advance,
Arthur
Good, quick hack; however, there is one flaw in particular that stuck out to me. If you use the <pre> element and white-space matters, you might want to improve the preg_match() by not removing duplicate spaces and linebreaks within <pre> elements.
Arthur,
I may be wrong here, but I put my paths relative to the webroot, not the physical root. So in your case, it would be:
php_value auto_prepend_file /arthauscommunications.com/global_prepend.php
Nice! One question though, it appears that if $_SERVER[’SERVER_NAME’] yields the server name set in Apache, so the result would be the same regardless if it was typed in mobile.myawesomeblog.com or http://www.myawesomeblog.com, at least that is what happened for me.
I found that the $_SERVER[’HTTP_HOST’] worked better as that provided the URL typed in the browser…
Then again I may have screwed something else up in Apache so…
There should be no difference between those two variables, but I would use SERVER_NAME if anything just because that is the typical method of retrieving the domain name as typed in the browser.
You can see what this variable (along with many others) is set to by making a simple PHP page that looks like the following:
<?php phpinfo(); ?>
If you are seeing a difference between these two variables, your server may have a problem.
Arthur: Dreamhost runs PHP as CGI by default. To switch it over so it runs as an Apache module, just go to “Domains > Manage > Edit” in the control panel. Then, uncheck the “run PHP as CGI” box. Also, if you have HTML pages on your site that aren’t PHP, you can force them through the PHP interpreter by adding this line to your .htaccess file:
AddType application/x-httpd-php .html .htm
Jordan: Good idea. Let me tweak the regex (or you could if you’d like, and I’ll get it merged in).
Justin: If Apache has been set up with one server name “mydomain.com”, I would assume that this is the name that is returned when using SERVER_NAME regardless if the address typed in is “mobile.mydomain.com” however the HTTP_HOST will return the typed address.
When trying phpinfo via localhost, HTTP_HOST indiates localhost, while SERVER_NAME indicates mydomain.com
As you said, there may be something wrong with the setup of the server.
Mike; I still cant get your hack to work just right, but again that may be the way my page is built up, or the serverconfig…
I have “similar” problems with htaccess where I try to implement a rewrite rule to change the way the address appear on my site, that won’t work either.
So I guess its likely to be something in the server set up.
If anyone have any idea of what may be wrong, I would appriciate the help.
Thank you.
> uncheck the “run PHP as CGI” box
How’d you leave that one out of the original article? I wonder what the effects of doing this are, since Dreamhost highly recommends that PHP is run as CGI (to put it in their words)?
Justin: I just added the note about PHP-as-CGI to the end of the original article. As for Dreamhost “highly recommending” running PHP as CGI, the only difference is that you won’t get to use some advanced things like the “exec()” command. You can always run it as CGI in the instances when you may need to.
Hi Mike,
I switched PHP to run as Apache. And still I see the same site (while loading http://mobile...)
I have all of the three files on top level. Since my Dreamhost account hold 15 domains. The three files (.htaccess + global_prepend.php + global_append.php) reside top-level of one of the domain.
My .htaccess file hase the following…
—
AddType application/x-httpd-php .html .htm
php_value auto_prepend_file /home/arthaus/arthauscommunications.com/global_prepend.php
php_value auto_append_file /home/arthaus/arthauscommunications.com/global_append.php
—
I must be doing something wrong!
Mike et al,
PHP as CGI is more secure and safe to use than PHP as module. There are a lot of aspects to it, and it’s much more than not being able to use some functions. However, increased security, good thing :-)
(and if anyone wants it, I can ask our sysadmin what all the major benefits and drawbacks are; I work at a webhost & webdevelopment company :-))
If you simply strip out all whitespace between brackets, what happens when you get something like this:
<b>Something in bold</b> <i>something in italics</i>
it will come out as
something in boldsomething in italics.
which has bitten me before.
I think it’s safer to just reduce all runs of whitespace to a single space, unless you want to use a more complicated regex.
Nice! As I am working on a redesign I will have to include this. Thanks!
What if you have ob_start() somewhere else in your PHP code (cached content)? Existing <meta name=”robots” content=”all”> - do the spiders only honor the last one found?
Great tutorial Mike!
(Editor’s Note: Not sure what happens in the case of multiple ob_starts. Should be easy to test though.)
Faruk, I would like to hear what the admin has to say about PHP as Apache vs. PHP as CGI. I know the CGI flavor is safer…but I don’t know why.
I don’t really know the current state of phone browsers as I haven’t been programming web sites for phones for about two and a half years. In the past most phones (I mean phones, not PDAs or PDA phones) ignored the CSS. My old Treo 600 didn’t support the handheld media type, but my Treo 650 does while also reading the other CSS files. The Blackberry units have horrible web support. The new units do support some CSS though, but don’t seem to recognize the handheld media type. For my site I provide a handheld CSS file that turns off what my screen CSS file does and pretty much follows the principles of creating a “zoom” layout.
Thanks for giving me the inspiration to take my website mobile. http://www.knoxvegan.com
This doesn’t look like it’s stripping style sheets that are referenced with @import. Is that the case? Any ideas on how to add that in?
(Editor’s Note: Thanks Dan. You’re right. I’ve just updated the code to fix this issue. Now all style tags are stripped as well.)
Thanks mike great tutorial :)
I’m willing to buy a mobile phone to show clients my site on the phone,
what phone do you guys think will be best for the job :)
There are various pros and cons to using php as CGI vs mod-php, the apache module.
URL frobbing: url?var=val&var2=val2 will work, but nothing tricksy will work with php cgi unless you use mod-rewrite.
Security: if you are using mod-suid, then cgi scripts will run as you, which means the files that your website holds will not be accessible to the scripts running in the websites of other users on the same machine. This is a significant security gotcha, but correctly setting apache’s ’suexec’ setting should resolve it.
I think there’re ways to make mod-php run suid, too, but I won’t swear to it.
More Security: mod-suid CGI scripts run as you, which means they have full access to your directory, and all your info, public or private. Major security gotcha, hard to getaround, but at least you’re not making other users vulnerable.
Directives: Custom PHP .htaccess directives require mod-php.
$_SERVER[’SCRIPT_NAME’] evaluates wrongly under cgi php.
Custom 404s. I think php-ified 404 pages need mod-php. At least, doing them with CGI is a bit of a pain.
Processes: as I understand it, cgi php launches a new process and loads in all the source and recompiles it every time you run a php script. mod-php caches the compiled versions of frequently used scripts instead.
On balance, mod-php is more powerful and can be more secure than cgi php, but requires a little more caution.
Hi Mike, I post my simple solution at the problem of set up subdomains that point to main site. It is probably the operation Dreamhost automatically makes. I have Cpanel and it works.
The steps are:
1. Create a subdomain “alfa” with your Control Panel
2. if the directory”alfa” in your web space has been created, remove it
3. Create symlink named “alfa” to public_html
4. End.
In Windows host, I don’t know if works.
Mike Just one thing I would like to point out ,aren’t mirror pages a bad thing for the search engines, as they penalize sites that have duplicate pages and mirror pages, is there another way without have to create the subdomain?
Regards Paul
OK, if we don’t get it listed in the engines - how do we let people know where the mobile version of the site is?
Looks great, but how do we get the faces in front of it?
It would also be interesting to not have the search engines banned from the subdomain - the changes listed may well be enough to make it ‘different’ content. I won’t be testing it though ;)
Paul: That’s what the “no-follow” thing in the replacement code takes care of. It makes sure the mobile pages don’t get indexed.
Lea: Yep, that’s an interesting question. I just have a little button in my sidebar. Ideally, the prefix “mobile.” would work on every site.
Isn’t the .mobi domain intended to do similar? Be a mobile variant of every site? (Silly idea.)
I wonder how one would convince the mobile makers to preset their browsers to check for existance of mobile.mydomain.com first when sent to http://www.mydomain.com?
:)
Hi Lea,
When the .mobi domain name comes you problay would only have to change the mobile.doamin.com url in the “global_prepend.php” to domain.mobi.
Is that correct Mike?
(Editor’s Note: Theoretically, yes… but you’d have to make a separate DNS entry for it I believe.)
Hi Guys
Just seen this article tried it out - fell over. Can make sub-domains. Pointing, do you mean redirect ’cause pointing I thought meant you needed to ‘park’ a domain first! And they have to be registered.
Ok when I enter the 2x lines into .htaccess (below) the whole website falls-over.
–
php_value auto_prepend_file /localfilepath/global_prepend.php
php_value auto_append_file /localfilepath/global_append.php
–
Anybody else get this or am I just a nobrainer. I did edit the .php files to reflect my site and subdomain by-the-way.
Anyone?
Regarding the poster earlier worried about people not following “web standards”. The real question is, is the “standard” better then a quick way that happens to get the job done exactly the way it needs to be?
Most people don’t know about “best practices”. In order to apply them, they would have to spend time learning something new. Perhaps many years. When do you stop learning and actually do something with what you’ve learned? Who do you trust to tell you what the “best practice” is? Industry? Someone who’s famous? A friend? An “altrusitic” organization? Suppose you apply it and it doesn’t work for you, who is at fault? Could it simply be that you are a different person then the one who tried it and succeeded doing it that way? And even if you decide you simply haven’t applied it correctly, how do you know that you will get the same end result that the successful person has?
The best advice any person can give to another is for them to simply do WHAT WORKS. I.E., if they like the result and it works for their situation, then that’s the correct practice, end of story. Telling them they have to go and learn a whole new way of being when they don’t want to because they are already getting what they want is counter-productive. The person simply won’t do it, and no amount of “but standards are better!” logic is going to convince them to change their minds. Nor should you try. They are happy, so you should be happy for them. And realize that YOUR way can be different, because you are different. So use the standard if it appeals to you, but realize that there WILL be people who don’t like the standard because it doesn’t meet their needs. Is that the fault of the person, or the standard itself?
Great tutorial. I posted an article on my blog about my integration experience (using Dreamhost, of course).
This will be super-easy to fix, just a matter of trial and error. Anyone recommend one route or the other?
Great tutorial, perfect for my needs, only I can’t get it to work. Setup the mirror subdomain no problem, set both auto_prepend_file and auto_append_file no problem, I have checked this by running a simply phpinfo script whichs shows my files are assigned. When I access any of the html files in the site there are no changes. I’m virtually sure you won’t have time to deal with my problems but I thought it was worth an ask seeing as I have spent 48hrs on a 2 min tutorial.