The best way to learn how to use the WebCore is by example. See the documentation for more information.
The requested URL is always shown first; if a page uses one or more WebCore templates, those are shown afterwards.
00 <?php
01 include_once ('software/init.php');
02
03 $Page->title->subject = 'earthli Browser Detector';
04 $Page->location->append ('Software', '../');
05 $Page->location->append ('Webcore', '../webcore/');
06 $Page->location->append ($Page->title->subject);
07
08 $Page->start_display ();
09
10 $path = $Page->resolve_path ('{data}software/browser_detector/downloads');
11 ?>
12 <div class="main-box">
13 <div class="columns text-flow">
14 <div>
15 <p>Finally a browser detector you can depend on. Let's face it, with all of the browsers
16 on the market today, you need a slightly more sophisticated tool than just searching
17 for 'MSIE' in the user agent, right?</p>
18 <p>There are browsers that spoof as other browsers so they get accepted at more sites
19 (Opera spoofing as IE); there are browsers built out of other browsers (AOL browser).</p>
20 <ul>
21 <li>How are you supposed to keep up with who's capable of doing what?</li>
22 <li>How many times have you adjusted your detection algorithm?</li>
23 <li>Or does it still just look for IE4 and NS4?</li>
24 <li>Do you want to run the kind of site that rejects an Opera user because your site
25 requires IE 5.x or higher?
26 </ul>
27 <p>Browser detection is not for the faint of heart. That's why you should be using the
28 earthli Browser Detector. We've done all of the leg work for you and come up with a
29 solid approach to picking apart a user agent and getting at the facts.</p>
30 <h3>What's so special about it?</h3>
31 <p>All browser detectors have to work with the <code>user agent string</code>. User agents can happily
32 lie about who they are. A liar will fool any browser detector, including this one. Most
33 browsers don't lie, and even those that spoof can't help writing their name in the user
34 agent string <em>somewhere</em>.</p>
35 <p>Where this browser detector parts ways with most is that it clearly separates its tasks:</p>
36 <dl>
37 <dt class="field">Find out the <em>name</em> of the browser.</dt>
38 <dd>That's the name the user's going to recognize.
39 Users are a little confused when you tell them they're browsing with IE when they're clearly
40 using the MSN browser. Users neither know nor care about the branding and the browser wars.</dd>
41 <dt class="field">Find out the <em>renderer</em> being used.<dt>
42 <dd>This is the part that's important to your web code.
43 Your website couldn't care less whether an MSN or AOL or pure IE browser is making the request:
44 the important detail is which version of IE is making the request</dd>
45 <dt class="field">Find out the <em>operating system</em> the browser is running on.</dt>
46 <dd>Though most of the cross-platform
47 browsers use cross-platform engines, the most notable one that doesn't is also the most popular. I'm
48 not naming names.</dd>
49 </dl>
50 <p>The detector will reliably figure out which browser and operating system is being used, then
51 consults a table of capabilities to let you know if a particular operation should be supported.
52 The algorithm, described below, should be quite forward-compatible (and has indeed proved to be with
53 subsequent browser releases) and only needs to be updated when:</p>
54 <ul>
55 <li>A new renderer hits the market, like Safari and Omniweb for the Mac moving to the KHTML
56 platform. Omniweb 5.0 is detected as based on the KHTML renderer, whereas previous versions still
57 identify as based on the Omniweb 4.x platform. OmniWeb 5.x and Safari are the <em>same</em> browser
58 as far as you're concerned because the rendering engine is the same.</li>
59 <li>A renderer suddenly sprouts new capabilities (like Opera did when moving from 6.x to 7.x (Presto)).</li>
60 </ul>
61 <p>The detector is table-driven, so even these types of changes were handled in 'data', without
62 changing the algorithm at all.</p>
63 <h3>What's the super-secret algorithm already?</h3>
64 <p>After careful analysis of an <a href="http://www.pgts.com.au/pgtsj/pgtsj0208c.html">enormous
65 list of available user agents</a>, a few similarities cropped up:</p>
66 <ul>
67 <li>Most browsers list a few browsers with which they are <em>compatible</em>. These are specified
68 in order of importance, from left to right. They are there to fool simpler detectors that only
69 do a substring search.</li>
70 <li>The actual name of the browser (MSN, AOL) comes after the list of renderers with which the
71 browser is compatible.</li>
72 <li>Some browsers (IE and Gecko variants) allow plugins to alter the user agent. These are usually
73 appended after the browser's real name.</li>
74 <li>Most browsers include the operating system information somewhere in the user agent.</li>
75 <li>All of these pieces of information are specified as 'name' 'separator' 'version numbers'. The
76 separator is not always the same (can be /-\: or a space).</li>
77 </ul>
78 <p>The earthli Browser Detector then defines a few tables from the information above:
79 <ul>
80 <li>A list of names for known rendering technologies.</li>
81 <li>A list of known operating systems.</li>
82 <li>A list of known plugin names.</li>
83 </ul>
84 <p>Armed with these, the algorithm reads from left to right, pulling out name/version pairs and executing
85 the following logic.</p>
86 <ol>
87 <li>Is this a recognized rendering technology?
88 <ol>
89 <li>If no renderer is recorded, use this one.</li>
90 <li><p>If this renderer is more <em>specific</em> than the current one, replace it.</p>
91 <p class="notes">What does this mean? Most browsers specify Mozilla/4.0 compatibility,
92 but they almost <em>always</em> specify a more specific renderer later in the string.
93 That allows things like 'Mozilla/4.0 MSIE/5.0' to be properly recognized as an Internet
94 Explorer rather than Mozilla browser.</p></li>
95 </ol>
96 </li>
97 <li>Is this an operating system name? (Linux browsers tend to provide specific information)
98 <ol>
99 <li>Record the name and version of the OS.</li>
100 </ol>
101 </li>
102 <li>Is this a known plugin name?
103 <ol>
104 <li>If <strong>not</strong>, record it as the browser's name and version. The last non-ignored
105 pair encountered is always treated as the browser's true name.</li>
106 </ol>
107 </li>
108 <li>Finish determining the operating system name and version?
109 <ol>
110 <li><p>Search the user agent for known OS strings that don't necessarily match the name/version
111 pair analyzed in the first phase.</p>
112 <p class="notes">The information found here is mixed with any OS information
113 already determined above. The OS info is actually available in two parts: <code>system_name</code>
114 and <code>interpreted_system_name</code>. The first is the version info directly extracted from the
115 string; the second is a user-friendly version recognizable to the user. For example, if Windows NT 5.0
116 is specified in the user agent, <code>interpreted_system_name</code> will return Windows 2000.</p></li>
117 </ol>
118 </li>
119 </ol>
120 <h3>How did you test it?</h3>
121 <p>The Phoenix browser (I know, I know, but that's what it was called when I did my tests)
122 provides a preference to change the user agent
123 transmitted in the HTTP header. This was used along with aforementioned <a href="http://www.pgts.com.au/pgtsj/pgtsj0208c.html">list
124 of user agents</a> to spoof as many different browsers in testing.</p>
125 <h3>How do I use it?</h3>
126 <p>All of the cool properties and values discovered during analysis are best used only for
127 displaying or recording information about a browser. Use the <code>supports</code> function
128 to find out whether a browser can or can't do something, like Alpha-PNGs, CSS2 or DHTML.
129 If you need to check a property that isn't covered by supports and its flags, you'll have to
130 use the <code>is</code> and the various name and version functions to do the test yourself.</p>
131 <p>There is <a href="docs.php">full documentation</a> for every function and property you need. You
132 can look up how <code>supports</code> uses <code>is</code> and version numbers.</p>
133 <p>If you do come up with a useful check, let me know and we'll build it into <code>supports</code> directly.
134 Or, better yet, do it yourself and mail it to me. I'll post an update with your changes in it.</p>
135 <h3>What about porting? Is this PHP only?</h3>
136 <p>The implementation is PHP only, but the algorithm is quite language-independent
137 and can easily be ported to any other language with regular expressions. At some point, there
138 should be a JavaScript version for those that would rather know all this stuff client-side. If
139 you're in a hurry, try porting it yourself ... it's relatively <a href="docs.php">well-documented</a> and should port
140 pretty much one-to-one.</p>
141 </div>
142 <div class="right-sidebar">
143 <h2>Demo</h2>
144 <?php $Page->start_icon_container('{icons}buttons/ship', Sixteen_px); ?>
145 <p>
146 See the <a href="demo/">demo</a>!
147 </p>
148 <?php $Page->finish_icon_container(); ?>
149 <h2>Download</h2>
150 <?php $Page->start_icon_container('{icons}buttons/download_to_hd', Sixteen_px); ?>
151 <p>
152 <a href="<?php echo $path; ?>earthli_browser_detector.zip">Download</a> it now!
153 </p>
154 <?php $Page->finish_icon_container(); ?>
155 <h2>Documentation</h2>
156 <?php $Page->start_icon_container('{icons}file_types/text_file', Sixteen_px); ?>
157 <p>
158 Read the <a href="docs.php">documentation</a>
159 </p>
160 <?php $Page->finish_icon_container(); ?>
161 <h2>WebCore</h2>
162 <?php $Page->start_icon_container('{site_icons}products/webcore', Sixteen_px); ?>
163 <p>
164 Part of the <a href="../webcore">earthli WebCore</a>
165 </p>
166 <?php $Page->finish_icon_container(); ?>
167 </div>
168 </div>
169 </div>
170 <?php $Page->finish_display (); ?>
171