<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss1full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
<channel rdf:about="http://dev.opera.com/">
<dc:date>2009-11-12T00:30:04Z</dc:date>
<dc:rights>Opera Software ASA</dc:rights>
<link>http://dev.opera.com/</link>
<title>Dev Opera Articles</title>
<description>Dev Opera is a community resource site where developers can share tips, tricks, extensions and more.</description>
<items>
<rdf:Seq>
<rdf:li rdf:resource="http://dev.opera.com/articles/view/858" />
<rdf:li rdf:resource="http://dev.opera.com/articles/view/849" />
<rdf:li rdf:resource="http://dev.opera.com/articles/view/800" />
<rdf:li rdf:resource="http://dev.opera.com/articles/view/796" />
<rdf:li rdf:resource="http://dev.opera.com/articles/view/801" />
<rdf:li rdf:resource="http://dev.opera.com/articles/view/855" />
<rdf:li rdf:resource="http://dev.opera.com/articles/view/842" />
<rdf:li rdf:resource="http://dev.opera.com/articles/view/790" />
<rdf:li rdf:resource="http://dev.opera.com/articles/view/783" />
<rdf:li rdf:resource="http://dev.opera.com/articles/view/817" />
</rdf:Seq>
</items>
<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/DevOperaFullFeed" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /></channel>
<item rdf:about="http://dev.opera.com/articles/view/858">
<creator>Masataka Yakura</creator>
<dc:date>2009-11-05T09:30:52Z</dc:date>
<link>http://feedproxy.google.com/~r/DevOperaFullFeed/~3/ZWp8ml-nd8g/858</link>
<title>4: Web 標準のモデル — HTML, CSS, JavaScript</title>
<description>&lt;img src="http://feeds.feedburner.com/~r/DevOperaFullFeed/~4/ZWp8ml-nd8g" height="1" width="1"/&gt;</description>
<feedburner:origLink>http://dev.opera.com/articles/view/858</feedburner:origLink></item>
<item rdf:about="http://dev.opera.com/articles/view/849">
<creator>Daniel Davis</creator>
<dc:date>2009-11-03T07:06:13Z</dc:date>
<link>http://feedproxy.google.com/~r/DevOperaFullFeed/~3/u2-9_mJZvtw/849</link>
<title>Opera Mobile 10 beta developer’s introduction</title>
<description>&lt;div class="article"&gt;&lt;h2&gt;Introduction&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.opera.com/mobile/next/"&gt;Opera Mobile&lt;/a&gt; is our web browser for high-end phones and we have just released a beta of version 10, which can be installed on Nokia smartphones. To find out more about whether your phone will run it and how to download it, visit our &lt;a href="http://www.opera.com/mobile/next/"&gt;Opera Mobile section&lt;/a&gt;. As well as being a double digit Opera Mobile release, Opera Mobile 10 beta is also the first Opera browser to use our Presto 2.4 rendering engine, which features enhanced standards support.&lt;/p&gt;

&lt;p class="note"&gt;Opera Mobile is a complete web browser installed on your mobile phone—all the code rendering and JavaScript interaction happens on your mobile. This is in contrast to &lt;a href="http://www.opera.com/mini/"&gt;Opera Mini&lt;/a&gt;, where the rendering happens on the server and a compressed version is then sent to the handset.&lt;/p&gt;

&lt;h2 id="mobile10features"&gt;Opera Mobile 10 features&lt;/h2&gt;

&lt;div class="right"&gt;
&lt;img src="Opera_Mobile_10_beta.png" alt="Opera Mobile 10 beta UI" /&gt;
&lt;p class="comment"&gt;Figure 1: Opera Mobile 10 beta UI&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Once you’ve installed Opera Mobile 10 and launched the application, the first thing you’ll notice is the new &lt;abbr title="User Interface"&gt;UI&lt;/abbr&gt;. Figure 1 demonstrates the new tabs, icons and also Speed Dial, the popular feature we pioneered in our desktop browser. Speed Dial has now been ported to Opera Mobile and appears when you start the browser, open a new tab or select Start Page from the menu, giving you fast access to your favorite sites.&lt;/p&gt;

&lt;p&gt;A lot of work has gone into streamlining the look and feel of our browser products across different devices, so using Opera Mobile 10 will be a familiar experience to anyone who has already used &lt;a href="http://www.opera.com/mini/next/"&gt;Opera Mini 5 beta&lt;/a&gt;, which we released in September.&lt;/p&gt;

&lt;p&gt;Like its big brother on the desktop, Opera Mobile 10 also features &lt;a href="http://www.opera.com/business/solutions/turbo/"&gt;Opera Turbo&lt;/a&gt;. If you are browsing the Web in an area of low or patchy bandwidth, you can turn on Opera Turbo to compress web sites by up to 70%, depending on your circumstances.&lt;/p&gt;

&lt;p&gt;If you dive into the &lt;em&gt;Settings&lt;/em&gt;, you’ll find many more options, such as &lt;em&gt;Mobile view&lt;/em&gt;, which displays content in a single column, as well as advanced privacy management settings and more. And just like its desktop counterpart, you can enter &lt;kbd&gt;opera:config&lt;/kbd&gt; in the address bar for power user tweaks.&lt;/p&gt;

&lt;h2&gt;The Opera Mobile 10 beta user agent string&lt;/h2&gt;

&lt;p&gt;Similar to &lt;a href="http://dev.opera.com/articles/view/opera-ua-string-changes/"&gt;Opera 10 for desktop&lt;/a&gt;, Opera Mobile 10 beta identifies as Opera 9.8, version 10.00. The user agent string is as follows: &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Opera/9.80 (S60; SymbOS; Opera Mobi/275; U; en-GB) Presto/2.4.13 Version/10.00&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Also note that in general, Opera can be identified by using JavaScript to test for the &lt;code&gt;window.opera&lt;/code&gt; object.&lt;/p&gt;

&lt;h2 id="optimizationmobile"&gt;Optimizing for mobile&lt;/h2&gt;

&lt;p&gt;Generally, you shouldn’t sniff for browsers and serve different content to different user agents. Instead, you can make your sites work well across a variety of devices and screen sizes using common HTML and CSS hooks. This section has more details on how to do this.&lt;/p&gt;

&lt;h3 id="viewport"&gt;Viewport meta tag&lt;/h3&gt;

&lt;p&gt;When loading a Web page in Opera Mobile, the user gets a zoomed out overview of the page and then can pan and zoom into selected content in just a few clicks. While this approach works fine for most websites, it is possible to further enhance the user experience by presenting an already zoomed in view of the page, thereby giving the page a more application-like feel.&lt;/p&gt;

&lt;p&gt;By including a viewport meta tag in the &lt;code&gt;head&lt;/code&gt; section of the page, content authors can override the default width a page gets on mobile—Opera Mobile assumes this is 850 pixels—and instead set an arbitrary pixel value, such as 320, 480, etc. For cross-device compatibility purposes and easy calculating, we recommend setting the width to the &lt;code&gt;device-width&lt;/code&gt; variable, as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;meta name="viewport" content="width=device-width" /&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This adjusts the page width to fit in the full width of the screen, or put differently, it makes one CSS pixel equal to one device pixel.&lt;/p&gt;

&lt;p&gt;A lot of websites use the viewport meta tag only on a different “mobile” URL, but it is worth pointing out that by combining it with Media Queries, it is possible to just have one page that works well and is optimized for several screen sizes.&lt;/p&gt;

&lt;h3 id="mediaqueries"&gt;Media Queries&lt;/h3&gt;

&lt;p&gt;Media Queries are a CSS3 feature that allow you to specify under what conditions a style sheet should be applied. They are included using the &lt;code&gt;@media&lt;/code&gt; at-rule, a media type, and optional expressions that limit the scope of the style sheet. For instance, to limit a style sheet to only apply to a screen with a viewport of 480 pixels or less, you could use the following Media Query:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@media screen and (max-width: 480px) {  
  background-color: red;
  font-size: 1.5em;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note the relationship to the viewport width here: in case the page is loaded in a desktop browser, the viewport width is the width of the browser window; in case it is loaded in Opera Mobile 10 beta, the viewport width is defined by the viewport meta tag, unless there is none present, in which case it defaults to 850 pixels.&lt;/p&gt;

&lt;p&gt;You can try this out for yourself by loading our &lt;a href="http://devfiles.myopera.com/articles/849/mq-viewport.html"&gt;Media Queries + viewport example&lt;/a&gt; in Opera Desktop and Opera Mobile 10 beta: on desktop, we get a three column layout for browser widths wider than 800 pixels—the page gets a different layout when the browser is resized. On Opera Mobile 10 beta, a viewport of &lt;code&gt;width=device-width&lt;/code&gt; (in the case of the Nokia 5800 in portrait mode this translates to 360 pixels) triggers the &lt;code&gt;@media screen and (max-width: 400px) {}&lt;/code&gt; style rules to be applied, and the three column page turns into a single column one.&lt;/p&gt;

&lt;h2 id="debugging"&gt;Improved remote debugging with Opera Dragonfly&lt;/h2&gt;

&lt;div class="right"&gt;
&lt;img src="dragonfly-highlight2.png" alt="Opera Dragonfly element highlight" /&gt;
&lt;p class="comment"&gt;Figure 2: Opera Dragonfly element highlight&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;As with earlier Opera Mobile releases, &lt;a href="http://www.opera.com/dragonfly/"&gt;Opera Dragonfly&lt;/a&gt; allows you to debug your web pages directly on your mobile phone. To debug pages in Opera Mobile 10 beta, open Opera Dragonfly in Opera Desktop (Tools → Advanced → Developer Tools) and follow the instructions in the Dev Opera &lt;a href="http://dev.opera.com/articles/view/remote-debugging-with-opera-dragonfly/"&gt;remote debugging&lt;/a&gt; article. As Opera Mobile 10 uses Presto 2.4, Opera Dragonfly will have to download a new compatible version before you can start debugging.&lt;/p&gt;
 
&lt;p&gt;The main new feature in Opera Dragonfly and Opera Mobile 10 beta is the element highlight. This feature highlights the metrics of the currently selected element. When clicking on a element, it is highlighted along with alignment guides. When clicking on the &lt;em&gt;Layout&lt;/em&gt; tab in the DOM inspector, you can hover over the different metrics such as the margin or padding to highlight that part of the element. The highlight colors are fully customizable (go to the &lt;em&gt;Settings&lt;/em&gt; tab and click on the &lt;em&gt;Spotlight&lt;/em&gt; heading.)&lt;/p&gt;

&lt;h2 id="standards"&gt;New standards support&lt;/h2&gt;

&lt;p&gt;Opera Mobile 10 beta is the first Opera browser release to feature our new Presto 2.4 rendering engine. The new engine supports everything featured in &lt;a href="http://www.opera.com/docs/specs/presto23/"&gt;Presto 2.3&lt;/a&gt;, plus some new additions.&lt;/p&gt;

&lt;p&gt;For this beta release, we have not enabled &lt;a href="http://my.opera.com/core/blog/2009/02/04/vega"&gt;Vega accelerated rendering&lt;/a&gt; yet, so features such as &lt;code&gt;border-radius&lt;/code&gt;, &lt;code&gt;box-shadow&lt;/code&gt;, etc. that depend on our Vega graphics backend don’t work for now. Also note that this is an early version of Presto 2.4 and not all standards features have been included in this release. We have more in the pipeline for future Opera Mobile 10 versions, so stay tuned.&lt;/p&gt;

&lt;p&gt;That being said, Presto 2.4 brings new support for a couple of interesting CSS properties to Opera Mobile 10 beta. In the sections below, we explore how you can use them in your website.&lt;/p&gt;

&lt;h3 id="bg-origin"&gt;Background-origin&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://devfiles.myopera.com/articles/849/bg-origin.html"&gt;Live &lt;code&gt;background-origin&lt;/code&gt; showcase&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://devfiles.myopera.com/articles/849/bg-origin_showcase.zip"&gt;&lt;code&gt;background-origin&lt;/code&gt; code download&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;background-origin&lt;/code&gt; and &lt;code&gt;background-repeat&lt;/code&gt; (see below) are part of the &lt;a href="http://www.w3.org/TR/css3-background/"&gt;CSS3 Backgrounds and Borders module&lt;/a&gt; and are closely related. Both showcases also use some oh-so-handy &lt;a href="#mediaqueries"&gt;Media Queries&lt;/a&gt; so the layout is optimized for both mobile and desktop users.&lt;/p&gt;

&lt;p&gt;The first showcase demonstrates &lt;code&gt;background-origin&lt;/code&gt;. This property specifies the starting point of any background image you apply to an element and the values it can take are as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;padding-box&lt;/code&gt;: Positions the background image relative to the outer edge of the padding (inner edge of the border). This is the default behavior.&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;border-box&lt;/code&gt;: Positions the background image relative to the outer edge of the border.&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;content-box&lt;/code&gt;: Positions the background image relative to the outer edge of the content (inner edge of the padding).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The example shows three &lt;code&gt;div&lt;/code&gt;s with the same background image applied to them and a similar double border. Each one has a different &lt;code&gt;background-origin&lt;/code&gt; value set on it. From left to right, these are &lt;code&gt;background-origin: padding-box&lt;/code&gt;, &lt;code&gt;background-origin:border-box&lt;/code&gt; and &lt;code&gt;background-origin:content-box&lt;/code&gt;. Figure 3 shows the different effects these have.&lt;/p&gt;

&lt;img src="background-origin_demo_mobile.png" alt="The difference between background-origin’s padding-box, border-box and content-box attributes." /&gt;
&lt;p class="comment"&gt;Figure 3: The difference between &lt;code&gt;background-origin:padding-box&lt;/code&gt;, &lt;code&gt;background-origin:border-box&lt;/code&gt; and &lt;code&gt;background-origin:content-box&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id="bg-repeat"&gt;Background-repeat&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://devfiles.myopera.com/articles/849/bg-repeat.html"&gt;Live &lt;code&gt;background-repeat&lt;/code&gt; showcase&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://devfiles.myopera.com/articles/849/bg-repeat_showcase.zip"&gt;&lt;code&gt;background-repeat&lt;/code&gt; code download&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second showcase highlights two new values for &lt;code&gt;background-repeat&lt;/code&gt;, namely &lt;code&gt;round&lt;/code&gt; and &lt;code&gt;space&lt;/code&gt;, both introduced to tidy up repeated background images that don’t fit neatly into your container.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;round&lt;/code&gt;: The background image is resized to fit in the container a whole number of times.&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;space&lt;/code&gt;: Whitespace is inserted between background images to fit in the container a whole number of times.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the two examples in Figure 4 the background images both have the same width of 100 pixels. In the first example, the dinosaur would normally appear two and a half times horizontally so the effect of &lt;code&gt;round&lt;/code&gt; here is to shrink the image so that three instances can fit in the container.&lt;/p&gt;

&lt;p&gt;The second example works in a similar way but whitespace is resized instead of images. Again, the dinosaur would normally appear two and a half times horizontally but the use of &lt;code&gt;space&lt;/code&gt; has resulted in just two images being displayed with padding between them.&lt;/p&gt;

&lt;img src="background-repeat_demo_mobile.png" alt="The difference between background-repeat’s round and space attributes." /&gt;
&lt;p class="comment"&gt;Figure 4: The difference between &lt;code&gt;background-repeat:round&lt;/code&gt; and &lt;code&gt;background-repeat:space&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id="wordwrap"&gt;Word-wrap&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://devfiles.myopera.com/articles/849/word-wrap.html"&gt;Live &lt;code&gt;word-wrap&lt;/code&gt; showcase&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Word-wrap is nice and straightforward taking either of two attributes, &lt;code&gt;normal&lt;/code&gt; or &lt;code&gt;break-word&lt;/code&gt;. The default setting is &lt;code&gt;normal&lt;/code&gt; meaning that lines are only broken at allowed break points such as spaces, for example. Changing this to &lt;code&gt;break-word&lt;/code&gt; forces words to be broken if they would otherwise overflow beyond their container, as in Figure 5.&lt;/p&gt;

&lt;img src="word-wrap_demo_mobile.png" alt="Word-wrap demo on Opera Mobile 10 beta" /&gt;
&lt;p class="comment"&gt;Figure 5: Word-wrap demo&lt;/p&gt;

&lt;p&gt;&lt;code&gt;word-wrap&lt;/code&gt; should not be confused with &lt;code&gt;text-wrap&lt;/code&gt; which sets the mode for text wrapping. Also note that &lt;code&gt;word-wrap&lt;/code&gt; is only effective if &lt;code&gt;text-wrap&lt;/code&gt; is set to &lt;code&gt;normal&lt;/code&gt; (default) or &lt;code&gt;suppress&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id="Summary"&gt;Summary&lt;/h2&gt;

&lt;p&gt;That wraps up our introduction to Opera Mobile 10 beta. We’ve taken you through its main new features and exciting new web standards support. As always, let us know how you like it!&lt;/p&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevOperaFullFeed/~4/u2-9_mJZvtw" height="1" width="1"/&gt;</description>
<feedburner:origLink>http://dev.opera.com/articles/view/849</feedburner:origLink></item>
<item rdf:about="http://dev.opera.com/articles/view/800">
<creator>Masataka Yakura</creator>
<dc:date>2009-10-20T08:16:52Z</dc:date>
<link>http://feedproxy.google.com/~r/DevOperaFullFeed/~3/ZT5RSLAIywM/800</link>
<title>3: インターネットのしくみ</title>
<description>&lt;div class="article"&gt;&lt;ul class="seriesNav"&gt;
&lt;li class="prev"&gt;&lt;a rel="prev" href="http://dev.opera.com/articles/view/2-the-history-of-the-internet-and-the-w-ja/"&gt;前の記事: インターネットと Web の歴史、そして Web 標準の進化&lt;/a&gt;&lt;/li&gt;
&lt;li class="next"&gt;&lt;a rel="next" href="http://dev.opera.com/articles/view/4-the-web-standards-model-html-css-a-ja/"&gt;次の記事: Web 標準のモデル — HTML, CSS, JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel="index" href="http://dev.opera.com/articles/view/1-introduction-to-the-web-standards-cur-ja/#toc"&gt;カリキュラムの目次へ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;p&gt;舞台の裏側で、歯車やベルトが回るのを見たことがあるでしょうか。今回は皆さんもよく知っている World Wide Web について、その舞台裏をお見せしましょう。&lt;/p&gt;
&lt;p&gt;World Wide Web を支えている技術には、次のようなものがあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTML (Hypertext Markup Language)&lt;/li&gt;
&lt;li&gt;HTTP (Hypertext Transfer Protocol)&lt;/li&gt;
&lt;li&gt;DNS (Domain Name System)&lt;/li&gt;
&lt;li&gt;Web サーバーと Web ブラウザー&lt;/li&gt;
&lt;li&gt;静的コンテンツと動的コンテンツ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらはインターネットの基盤技術ですから、この記事で解説することは、よい Web サイトを作るための手助けにはあまりならないでしょう。しかし、クライアントなど他人と Web について話す時に適切な意思疎通を行うための言葉を知る事ができます。&lt;em&gt;サウンド･オブ･ミュージック&lt;/em&gt;でマリアが「読み書きを ABC から始めるのとおなじで、歌はドレミの歌から始めるの」と言ったのと同じです。&lt;/p&gt;

&lt;p&gt;今回は、コンピューター同士が HTTP や TCP/IP を通じて通信する仕組みを簡単に説明してから、Web ページを構成する技術について見ていきます。目次は次のとおりです。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#internetcommunication"&gt;インターネット上でコンピューターが行う通信&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#requestresponse"&gt;リクエスト/レスポンスサイクルの詳細&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="#contenttypes"&gt;コンテンツの種類&lt;/a&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="#plaintext"&gt;プレーンテキスト&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#webstandards"&gt;Web 標準&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#dynamicpages"&gt;動的な Web ページ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#proprietaryformats"&gt;他のアプリケーションやプラグインを必要とするフォーマット&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href="#staticdynamic"&gt;静的な Web サイト vs. 動的な Web サイト&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#summary"&gt;まとめ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#exercises"&gt;練習問題&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="internetcommunication"&gt;インターネット上でコンピューターが行う通信&lt;/h2&gt;

&lt;p&gt;コンピューター関する技術は、幸いな事にシンプルに保たれてきました。World Wide Web について言えば、ほとんどのページが HTML という共通の言語で書かれていますし、これらは共通のプロトコルである HTTP (Hypertext Transfer Protocol) で配信されています。HTTP は共通語 (仕様) ですから、たとえば Windows マシンと最新の Linux マシンが通信することも可能なのです。&lt;/p&gt;

&lt;p&gt;そして、Web ブラウザーという HTTP を解釈し HTML を人間に可読可能なかたちに整形してくれるソフトウェアのおかげで、HTML で書かれたページにはコンピューターからだけではなく、電話や PDA、さらには人気のゲーム機からもアクセスすることができるのです。&lt;/p&gt;

&lt;p&gt;しかし、同じ言葉を話していたとしても、Web にアクセスするデバイスは多種多様ですから、お互いに通信するための何かしらのルールが必要です。学ぶために授業で手を挙げるようなものですね。インターネットにおいて、このルールが HTTP になるわけです。HTTP のおかげで、クライアントマシン (あなたのコンピューター) は、自身を「&lt;strong&gt;サーバー&lt;/strong&gt;にサイトをリクエストするもの」と認識できるのです。&lt;/p&gt;

&lt;p&gt;サーバーとは、Web サイトが存在するコンピューターになります。Web アドレスをブラウザーに打ち込むと、サーバーはそのリクエストを受け取り、要求されたページを見つけ出してあなたのコンピューターに送り返します。送り返されたデータは最終的にブラウザー上で表示されます。&lt;/p&gt;

&lt;h3 id="requestresponse"&gt;リクエスト/レスポンスサイクルの詳細&lt;/h3&gt;

&lt;p&gt;さて、コンピューターがインターネット上でどのように通信するのかを説明したので、今度は HTTP のリクエスト/レスポンスの流れについてもうちょっと詳しく説明しましょう。いくつかの概念を効果的に説明したいので、ステップに分けて話しますね。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;すべてのリクエスト/レスポンスは、Web ブラウザーのアドレスバーに URL (Univeral Resource Locator) を打ち込むすることから始まります。URL はたとえば &lt;a href="http://dev.opera.com" target="_blank"&gt;http://dev.opera.com&lt;/a&gt; のようなものになります。ではここで、ちょっとこの URL を打ち込んでみてください。&lt;/p&gt;

&lt;p&gt;さて、ここで一つ、あなたが知らないかもしれないことをお話します。実は、Web ブラウザーはサーバーに Web サイトをリクエストする際、URL を利用していないのです。ブラウザーは代わりに、&lt;strong&gt;IP アドレス&lt;/strong&gt; (&lt;strong&gt;Internet Protocol&lt;/strong&gt;) というものを利用します。IP アドレスは電話番号や郵便番号など、サーバーを識別するものになります。たとえば、先ほどの &lt;a href="http://dev.opera.com" target="_blank"&gt;http://dev.opera.com&lt;/a&gt; の IP アドレスは 213.236.208.98 になります。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;では、新しいタブかウインドウを開いて、http://www.apple.com と打ち込み Enter を押してください。次に &lt;a href="http://17.149.160.10/" target="_blank"&gt;http://17.149.160.10/&lt;/a&gt; と打って Enter を押してみてください。同じページが現れるはずです。では、http://213.236.208.98 とタイプして Enter を押してください。この IP アドレスは先ほど紹介した、http://dev.opera.com と同じサーバーに接続します。ただし、あなたが見るのは 403 “Access Denied” というエラーでしょう。これは、サーバーの実際のルートへのアクセスが許可されていないことによるものです。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.apple.com" target="_blank"&gt;http://www.apple.com&lt;/a&gt; は基本的に &lt;a href="http://17.149.160.10/" target="_blank"&gt;http://17.149.160.10/&lt;/a&gt; のエイリアスとして機能しています。しかし、一体なぜこのような仕組みがあり、またどのように機能しているのでしょうか？&lt;/p&gt;

&lt;p&gt;まず、このような仕組みを導入する理由ですが、これは人間が数字の羅列を覚えるよりも、単語のほうが記憶しやすいということに基づいています。そして、これを実現する仕組みがDNS (Domain Name System) と呼ばれるものになります。DNS は言わば、インターネットに接続するマシンを自動的に収集する辞書になります。&lt;/p&gt;

&lt;p&gt;あなたがアドレスバーに &lt;a href="http://dev.opera.com" target="_blank"&gt;http://dev.opera.com&lt;/a&gt; と入力し Enter を押したとき、このアドレスはネームサーバーに送られ、対応する IP アドレスへの結びつけを行います。インターネットには膨大なマシンがあり、すべての DNS サーバーがオンラインのマシン全てを網羅しているわけではありません。ですから、あなたの要求をかなえるべく、リクエストを適切なサーバーに受け渡す仕組みが備わっています。&lt;/p&gt;

&lt;p&gt;DNS システムは www.opera.com という Web サイトを探し、17.149.160.10 という対応するIPアドレスを見つけます。そして、その IP アドレスを Web ブラウザーに返すのです。&lt;/p&gt;

&lt;p&gt;あなたのマシンは、指定された IP アドレスにあるマシンにリクエストを送信し、レスポンスが帰ってくるのを待ちます。すべてがうまくいけば、サーバーはページと共に、クライアントに全てが OK という短いメッセージを送信します (図1)。このメッセージは &lt;strong&gt;HTTP ヘッダー&lt;/strong&gt;に格納されています。&lt;/p&gt;

&lt;img alt="リクエスト/レスポンスサイクルの成功例" src="article3_1.png" /&gt;

&lt;p class="comment"&gt;図1: この通信には何も問題がないので、サーバーは適切なWebページを返します&lt;/p&gt;

&lt;p&gt;もし何か間違いがあったとき、たとえばURLのタイプミスがある場合、Web ブラウザーは &lt;strong&gt;HTTP エラー&lt;/strong&gt;を受け取ります。悪評高い 404  “Page Not Found” エラーはその最たる例です。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;今度は &lt;a href="http://dev.opera.com/joniscool.html" target="_blank"&gt;http://dev.opera.com/joniscool.html&lt;/a&gt; とタイプしてください。実は、このページは存在しません。ですから404エラーが現れます。同じようにほかのサイトでも、存在しないであろうページにアクセスしてください。異なるエラーページが現れることがあると思います。これは、Web 開発者がサーバーが初期状態で持っているエラーページをそのまま利用したか、それともエラーページをカスタマイズしたかの違いです。これらは高度なテクニックですので、このコースでは取り上げませんが、dev.opera.com の他の記事で公開されればよいなと思っています。&lt;/p&gt; 

&lt;p&gt;さて、ほとんどの場合、Web サイトのトップページの URL にはファイル名がありません (例: &lt;a href="http://www.mysite.com/)。トップページ以下のページでも、URL" target="_blank"&gt;http://www.mysite.com/)。トップページ以下のページでも、URL&lt;/a&gt; にファイル名があるものと無いものが存在します。しかし、URL にファイル名がなくても、あなたは実ファイルにアクセスしているのです。これは訪れる人が URL を覚えやすいようにと、Web 開発者がサーバーの設定を変更し、ファイル名を隠すようにしているのです。このやり方についてもコースで取り上げることはしませんが、&lt;a href="http://dev.opera.com/articles/view/supplementary-getting-your-content-onli/" hreflang="en"&gt;サーバーにファイルをアップロードする方法や、ファイル/ディレクトリ構造の紹介&lt;/a&gt;についての記事が dev.opera.com で公開されています。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id="contenttypes"&gt;コンテンツの種類&lt;/h2&gt;

&lt;p&gt;今度はインターネットで見られるさまざまなコンテンツの種類について説明しようと思います。種類は大きく分けて4つ。プレーンテキスト、Web 標準、動的な Web ページ、そしてプラグインや他のアプリケーションを必要とするフォーマットになります。&lt;/p&gt;

&lt;h3 id="plaintext"&gt;プレーンテキスト&lt;/h3&gt;

&lt;p&gt;インターネットが始まった頃、つまり Web 標準やプラグインなどがまだ存在しなかった頃、インターネット上でやり取りされるデータは、画像と「.txt」といった拡張子を持つプレーンテキストファイルがほとんどでした。プレーンテキストはブラウザーで特に処理も行われず、そのまま表示されるだけです。こういったプレーンテキストファイルは、今でも大学の Web サイトなどで見つけることができます。&lt;/p&gt;

&lt;h3 id="webstandards"&gt;Web 標準&lt;/h3&gt;

&lt;p&gt;World Wide Web は、HTML (または XHTML)、CSS、JavaScript という3つの Web 標準によって組み立てられます (この記事では、HTML と XHTML が意味するものに大きな違いはありません)。&lt;/p&gt;

&lt;p&gt;Hypertext Markup Language という名前は、その目的を簡潔に伝えている点でとても優れています。HTML は文書を分割し、構造と内容を記述し、そして各部分に意味を与えるために使われます (あなたが Web サイトで見るテキスト情報は、すべてこの HTML に含まれています)。HTML ではページ内の異なるコンポーネントを、要素を使って識別します。&lt;/p&gt;

&lt;p&gt;Cascading Style Sheets によって、HTML 文書内の要素がどのように表示されるかが決定されます。CSS はとても簡単で、スタイル宣言を書くだけで、段落中の行間すべてをダブルスペースに (&lt;code&gt;line-height: 2em;&lt;/code&gt;) することや、第2レベルの見出しをすべて緑色に (&lt;code&gt;color: green;&lt;/code&gt;) することができます。&lt;/p&gt;

&lt;p&gt;構造とその表示を分けることにはたくさんの利点があります。これについては&lt;a href="http://dev.opera.com/articles/view/4-the-web-standards-model-html-css-a-ja/" title="Web 標準のモデル"&gt;次の記事&lt;/a&gt;で詳しく解説しますので、お楽しみに。&lt;/p&gt;

&lt;p&gt;HTML と CSS を組み合わせることでどんな変化があるのかを、図2で表してみました。整形情報が全くない plain な HTML が左に、その HTML ファイルに CSS で整形したものが右になります。&lt;/p&gt;

&lt;img alt="プレーンなHTMLと、そのHTMLにCSSを付加した例" src="http://dev.opera.com/articles/view/3-how-does-the-internet-work/article3_2.gif" /&gt;
 
&lt;p class="comment"&gt;Figure 2: プレーンなHTMLと、そのHTMLにCSSを付加した例&lt;/p&gt;

&lt;p&gt;そして、JavaScript はあなたの Web サイトに動的な機能を付加します。JavaScript はクライアントのコンピューターで動作し、サーバーに特別なソフトウェアをインストールする必要がありません。しかし、基本的な機能とインタラクティビティは JavaScript によって実現できますが、それにも限界があるため、高度なことをするにはサーバーサイドで動作するプログラミング言語や、動的な Web ページを必要とします。&lt;/p&gt;

&lt;h3 id="dynamicpages"&gt;動的な Web ページ&lt;/h3&gt;

&lt;p&gt;インターネットをブラウズしているときに、「.html」という拡張子ではないページに出くわすことがあると思います。たぶん、「.php」や「.asp」「.aspx」「.jsp」といった、ふしぎな拡張子がついているものと思われます。これらが、動的 Web 技術を利用したページになります。&lt;/p&gt;

&lt;p&gt;動的な Web ページは、ページに渡す値によって異なる結果が表示されます。データは、データベースやフォーム、その他のデータソースから渡されます。静的なページと動的なページの種類については、後で詳しく触れようと思います。&lt;/p&gt;

&lt;h3 id="proprietaryformats"&gt;他のアプリケーションやプラグインを必要とするフォーマット&lt;/h3&gt;

&lt;p&gt;Web ブラウザーは、Web 標準のような特定の技術しか解釈し表示することができません。ですから、複雑なファイル形式やプラグインを必要とする技術を利用した Web ページに出くわすと、ブラウザーはファイルのダウンロードを行うか、インストールされたプラグインを利用してコンテンツを処理しようとします。次のようなコンテンツが例として挙げられます。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Word 文書、Excel ファイル、PDF、圧縮ファイル (ZIP、SITなど)、Photoshop PSD のような複雑な画像ファイル、その他理解できないファイルに出くわすと、Web ブラウザーはそのファイルをダウンロードするか、それとも実行するかをユーザーに尋ねます。どちらも同じような結果になりますが、後者の場合は一度ファイルをダウンロードしたあとで、実行可能なアプリケーションがクライアントにインストールされている場合にファイルを開きます。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Flash ムービー、MP3 に代表される音楽フォーマット、MPEG などのビデオフォーマットの場合、ブラウザーはインストールされているプラグインを利用してファイルを再生します。もしプラグインが用意されていない場合、ブラウザーはプラグインをインストールするページへのリンクを提示するか、ファイルをダウンロードし、実行可能なソフトウェアを探します。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;もちろん、この両方に当てはまるようなものもあります。たとえば、SVG (Scalable Vector Graphics) は、Opera などいくつかのブラウザーでネイティブサポートが行われている Web 標準ですが、そうではないブラウザーもあります。たとえば、Internet Explorer は SVG をサポートしていないため、表示にはプラグインのインストールが必要です。しかし、多くのブラウザーはいくつかのプラグインをプリインストールしているため、あなたはそのコンテンツがプラグインで実行されているのか、それともブラウザーがネイティブでサポートしているのかが分からないかもしれません。&lt;/p&gt;

&lt;h2 id="staticdynamic"&gt;静的な Web サイト vs. 動的な Web サイト&lt;/h2&gt;

&lt;p&gt;「静的な Web サイト」「動的な Web サイト」とは一体なんでしょうか。そして、両者にはどのような違いがあるのでしょうか。&lt;/p&gt;

&lt;p&gt;チョコレートのアソートと同じで、すべてはその中身にあります。静的な Web サイトは、HTML や画像などのコンテンツが常に静的であることを表します。つまり、管理者がサーバー上のファイルを変更しない限りは、誰に対しても常に同じコンテンツが提供されます。これはまさしく、私達がこの記事で見てきたことになります。&lt;/p&gt;

&lt;p&gt;これに対して動的な Web サイトは、サーバー上のコンテンツは一緒ですが、HTML だけではなく動的なコードも含みます。これにより、利用者が Web サイトに提供するデータにあわせて表示が変わります。&lt;/p&gt;

&lt;p&gt;ちょっと試してみましょう。www.amazon.com にアクセスして、違う製品を5つ検索しててください。出てくる結果は異なりますが、Amazon は異なるページを返しているわけではないのです。Amazon はユーザーに同じページを送信するのですが、その際に入力に応じた情報が動的に盛り込まれるのです。情報はデータベースに保存されており、リクエストに応じて適切な情報を取得します。Web サーバーはそのデータを得て、動的なページに挿入するという仕組みです。&lt;/p&gt;

&lt;p&gt;もうひとつ付け加えたいのが、動的な Web サイトの構築には特別なソフトウェアをサーバーにインストールする必要があるということです。静的な HTML は「.html」という拡張子で保存されますが、動的な Web サイトのコンテンツには HTML のほかに動的なコードが含まれており、拡張子も特別なものになります。拡張子を変えることで、そのファイルはクライアントに提示される前にサーバー側で特別な処理されなければならないものであることを伝えるわけです。特別な処理とは、たとえばデータベースからデータを取得し、ページに埋め込むといったことが挙げられます。拡張子の例ですが、たとえば PHP ファイルには「.php」という拡張子がつけられています。&lt;/p&gt; 

&lt;p&gt;世の中にはさまざまな動的言語があります。いま挙げた PHP の他にも Python、Ruby on Rails、ASP.NET、Coldfusion といったものが有名です。これらの言語でできることにあまり違いはありません。どの言語でもデータベースへの接続や、フォーム入力の検証は行えるのです。しかし、言語によってそのやり方はすこしずつ異なっており、それぞれに長所や短所があります。ですから、最終的には何があなたに一番あっているかによるでしょう。&lt;/p&gt;

&lt;p&gt;このコースでは動的言語についてこれ以上取り上げることはありませんが、いくつかのリソースを紹介しようと思います。気になった方は読んでみてください。&lt;/p&gt;

&lt;p class="note"&gt;3番目にある PHP のマニュアルを除き、以下の書籍・Web サイトは英語で書かれています。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rails: Fernandez, Obie. (2007), The Rails Way. Addison-Wesley Professional Ruby Series.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.rubyonrails.org/screencasts"&gt;Rails screencasts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;PHP: Powers, David (2006), PHP Solutions: Dynamic web development made easy, friends of ED.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.php.net/docs.php"&gt;PHP Online documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ASP.NET: Lorenz, Patrick. (2003). ASP.NET 2.0 Revealed.  Apress.&lt;/li&gt;
&lt;li&gt;ASP.NET: &lt;a href="http://asp.net"&gt;online ASP.NET documentation and tutorials.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="summary"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;これで、インターネットの仕組みを紹介する舞台裏ツアーはおしまいです。この記事では、多くのトピックをちょっとずつ引っかいた程度ですが、各々の技術や概念がどう組み合わさって動いているのかをひとまとめに知ることができたのではないかと思います。&lt;/p&gt;

&lt;p&gt;HTML、CSS、JavaScript の構文などにはまだ触れていませんが、これは次の記事で詳しく解説します。Web ページのコードを見ながら、HTML、CSS、JavaScript という、Web 開発における「標準的な」モデルについて学んでいきましょう。&lt;/p&gt;

&lt;h2 id="exercises"&gt;練習問題&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;HTML と HTTP の定義と、それら二つの違いを説明しましょう。&lt;/li&gt;
&lt;li&gt;Web ブラウザーの役割を説明しましょう。&lt;/li&gt;
&lt;li&gt;インターネットを5分から10分程度散策し、記事内で説明したさまざまな種類のコンテンツを見つけましょう。プレーンテキストや画像、HTML、PHP や .NET (.aspx) のページ、PDF、Word 文書、Flash ムービーなどがその例です。コンテンツを見つけたらそれらにアクセスし、コンピューターがどのようにそれらのファイルを表示するかを考えてください。&lt;/li&gt;
&lt;li&gt;静的なページと動的なページの違いはなんでしょうか。&lt;/li&gt;
&lt;li&gt;HTTP エラーコードのリストを見つけ、その中から5つを選び説明しましょう。&lt;/li&gt;
&lt;/ul&gt;

&lt;ul class="seriesNav"&gt;
&lt;li class="prev"&gt;&lt;a rel="prev" href="http://dev.opera.com/articles/view/2-the-history-of-the-internet-and-the-w-ja/"&gt;前の記事: インターネットと Web の歴史、そして Web 標準の進化&lt;/a&gt;&lt;/li&gt;
&lt;li class="next"&gt;&lt;a rel="next" href="http://dev.opera.com/articles/view/4-the-web-standards-model-html-css-a-ja/"&gt;次の記事: Web 標準のモデル — HTML, CSS, JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel="index" href="http://dev.opera.com/articles/view/1-introduction-to-the-web-standards-cur-ja/#toc"&gt;カリキュラムの目次へ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;著者紹介&lt;/h2&gt;

&lt;img alt="著者 Jonathan Lane の写真" src="http://dev.opera.com/articles/view/3-how-does-the-internet-work/Jonlane.jpg" class="right" /&gt;

&lt;p&gt;Jonathan Lane はカナダのブリティッシュコロンビア州メーンアイランドにある Web 開発会社 &lt;a href="http://industryinteractive.net/"&gt;Industry Interactive&lt;/a&gt; の President を務めています。彼はレスブリッジ大学の Curriculum Re-Development Center にて長年にわたり、Web プロジェクトの取りまとめを行っていました。&lt;/p&gt;

&lt;p&gt;彼のブログは &lt;a href="http://www.flyingtroll.com/"&gt;Flyingtroll&lt;/a&gt; になります。また、プロジェクト管理アプリケーション Basecamp をEメールから利用可能にするアプリケーション「&lt;a href="http://www.mailmanagr.com/"&gt;Mailmanagr&lt;/a&gt;」の開発を行っています。&lt;/p&gt;

&lt;h2&gt;翻訳者について&lt;/h2&gt;

&lt;img alt="翻訳者矢倉眞隆の写真" src="mitsue-myakura.jpg" class="right" /&gt;

&lt;h3&gt;矢倉 眞隆 (Masataka Yakura)&lt;/h3&gt;
&lt;p&gt;1984年生まれ。株式会社ミツエーリンクスにて、社内の品質改善活動や Web 標準 の普及啓蒙を行っている。W3C HTML WG メンバー。&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://www.mitsue.co.jp/"&gt;株式会社 ミツエーリンクス&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;
1990年創業。大規模な Web サイト開発を得意とするインフォメーション・インテ グレータ。自社コンテンツの &lt;a href="http://standards.mitsue.co.jp/"&gt;Web 標準 Blog&lt;/a&gt; や&lt;a href="http://accessibility.mitsue.co.jp/"&gt;アクセシビリティ Blog&lt;/a&gt; より、Web フロントエンド技術に関するさまざまな情報を発信中。&lt;/p&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevOperaFullFeed/~4/ZT5RSLAIywM" height="1" width="1"/&gt;</description>
<feedburner:origLink>http://dev.opera.com/articles/view/800</feedburner:origLink></item>
<item rdf:about="http://dev.opera.com/articles/view/796">
<creator>Masataka Yakura</creator>
<dc:date>2009-10-20T08:14:58Z</dc:date>
<link>http://feedproxy.google.com/~r/DevOperaFullFeed/~3/aTXiTRCygvk/796</link>
<title>2: インターネットと Web の歴史、そして Web 標準の進化</title>
<description>&lt;div class="article"&gt;&lt;ul class="seriesNav"&gt;
&lt;li class="prev"&gt;&lt;a rel="start" href="http://dev.opera.com/articles/view/1-introduction-to-the-web-standards-cur-ja/"&gt;前の記事: Web 標準カリキュラムの紹介&lt;/a&gt;&lt;/li&gt;
&lt;li class="next"&gt;&lt;a rel="next" href="http://dev.opera.com/articles/view/3-how-does-the-internet-work-ja/"&gt;次の記事: インターネットのしくみ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel="index" href="http://dev.opera.com/articles/view/1-introduction-to-the-web-standards-cur-ja/#toc"&gt;カリキュラムの目次へ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;はじめに&lt;/h2&gt;

&lt;blockquote&gt;
    &lt;p&gt;&lt;q&gt;どこから始めればよろしいでしょうか、陛下？&lt;/q&gt;&lt;/p&gt;
    &lt;p&gt;&lt;q&gt;最初から始めよ。&lt;/q&gt; と、王様は重々しく口を開きます。 &lt;q&gt;最後まで続け、そこで止めよ。&lt;/q&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;―ルイス・キャロル『不思議の国のアリス』&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;全てのものには「はじまり」があります。ですから、このカリキュラムも歴史を紐解くことから始めましょう。この記事では、インターネットと World Wide Web、 そしてこのコースのテーマである&lt;q&gt;Web標準&lt;/q&gt;のはじまりについて簡単に紹介します。&lt;/p&gt;

&lt;p&gt;この記事は、インターネットや Web がどのような出来事を通じ現在に至ったのかを理解するのにとても役立つと思います。文章も長くありませんから、情報に圧倒されることなく詳細にすばやくたどり着けるでしょう。&lt;/p&gt;

&lt;p&gt;記事の中には、あなたの良く知らない単語が出てくるかもしれません。でも、そんなに心配しないでください。それが Web 開発を学ぶにあたって重要な概念であれば、後々の記事でその詳細を含めちゃんと説明してくれるはずです。もちろん、検索することだってできますし。&lt;/p&gt;

&lt;p&gt;ただ、すでにインターネットや World Wide Web の歴史を知っているのであれば、どうぞ &lt;a href="#comingofstandards"&gt;Web 標準&lt;/a&gt;のセクションから始めてください。記事は次のような構成になっています。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#internetorigins"&gt;インターネットのはじまり&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="#webcreation"&gt;World Wide Web の創成&lt;/a&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="#browserwars"&gt;&lt;q&gt;ブラウザー戦争&lt;/q&gt;の勃発&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="#comingofstandards"&gt;Web 標準の到来&lt;/a&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="#w3cformation"&gt;W3C の設立&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#webstandardsproject"&gt;Web Standards Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#riseofstandards"&gt;Web 標準の高まり&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="#summary"&gt;まとめ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#furtherreading"&gt;関連資料&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#exercisequestions"&gt;練習問題&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="internetorigins"&gt;インターネットのはじまり&lt;/h2&gt;

&lt;p&gt;1957年10月4日。この日、世界を変える出来事が起こりました。ソビエト連邦が史上初めて、地球軌道上に人工衛星を発射することに成功したのです。&lt;q&gt;スプートニク1号&lt;/q&gt;と呼ばれたこの人工衛星は、世界中に衝撃を与えました。中でも、人工衛星の発射計画を進めていたアメリカ合衆国にとって、そのショックはとても大きなものでした。&lt;/p&gt;

&lt;p&gt;この出来事は、アメリカ国防総省に高等研究計画局 (Advanced Research Projects Agency, ARPA) の設立をもたらしました。その時点での需要を越えた、より高等な概念や技術を研究・開発する機関の必要性が認められたからです。そして、ARPAで進められたプロジェクトのうち、おそらくもっとも有名なもの (そして、もっとも使われているであろうもの) が、インターネットなのです。&lt;/p&gt;

&lt;p&gt;1960年に、心理学者でありコンピューターサイエンティストである Joseph Licklider は、&lt;q&gt;人とコンピューターの共生 (Man-Computer Symbiosis)&lt;/q&gt;という論文を発表しました。この論文は、コンピューターネットワークによる先進的な情報の保管・検索を提供する概念を提唱したものでした。&lt;/p&gt;

&lt;p&gt;ARPA で情報処理オフィスを率いる傍ら、Licklider は1962年にコンピューター研究を進めるグループを組織しました。しかし、実際に研究に取り掛かる前に、彼はグループを抜けてしまいました。&lt;/p&gt;

&lt;p&gt;後に &lt;q&gt;ARPANET&lt;/q&gt; と呼ばれるこのコンピューターネットワークの計画は、1967年の10月に提出されました。そして2年後の1969年12月に、最初のコンピューターネットワークが稼動しました。&lt;/p&gt;

&lt;p&gt;ネットワークの構築にあたりもっとも大きな課題は、物理的に離れたネットワーク間で、リソースを圧迫することなく常時通信を行う仕組みを考え出すことでした。この問題を解決したのが、パケット交換と呼ばれる技術でした。パケット交換は、データリクエストを&lt;q&gt;パケット (packets)&lt;/q&gt;と呼ばれる細かい単位に分割し、他のパーティとの通信を遮断することなくデータを高速に処理できる仕組みです。このパケット交換は、今日のインターネットでも利用されている概念です。&lt;/p&gt;

&lt;p&gt;この考え方は広く採用され、結果として同じパケット交換技術を利用した異なるネットワークが出現することになりました。たとえば、国際電気通信連合 (ITU) によって開発されたX.25は、最初のイギリスの大学ネットワークである &lt;abbr title="Joint Academic Network"&gt;JANET&lt;/abbr&gt; を組織し、大学同士のファイルやEメールのやり取りを可能としました。また、アメリカの公共ネットワークである CompuServe も、X.25によって構築されました (CompuServe は営利企業ですが、小企業や個人を時分割制御のコンピューターリソースにアクセスすることを許可し、後にインターネットへのアクセスも許可していました)。これらのネットワークには多くの人が集いましたが、現在のインターネットと比べるとずっと閉じたものでした。&lt;/p&gt;

&lt;p&gt;異なるネットワークプロトコルの激増はすぐに問題となりました。なぜなら、異なるネットワーク間で相互通信を行う際に、プロトコルの違いを乗り越える必要があったからです。しかし幸いにも、すぐにその解決策が生み出されました。ARPA で人工衛星のパケットネットワークプロジェクトに従事していた Robert Kahn が、当時の ARPANET で使われていたプロトコルを置き換える、より開かれたネットワークアーキテクチャの定義に乗り出していたのです。&lt;/p&gt;
&lt;p&gt;後にスタンフォード大学の Vinton Cerf が加わり、ふたりはネットワークプロトコルの違いを覆い隠すシステムを新しい標準とともに開発しました。1974年12月に公開されたその仕様の草案には、&lt;q&gt;Internet Transmission Control Program&lt;/q&gt; という名前がつけられていました。&lt;/p&gt;

&lt;p&gt;この仕様は、ネットワークの役割を削減し、伝送品位の管理責任をホストコンピューターに移管するものでした。すなわち、ほぼ全てのネットワークを簡単に相互接続可能としたのです。ARPA はこのソフトウェア開発に投資し、1977年には3つの異なるネットワーク間での通信実験が成功しました。仕様はその後公開され、1981年の時点ではすでに幅広く利用されるようになっていました。&lt;/p&gt;
&lt;p&gt;1982年には、アメリカ以外からの ARPANET 接続は、すべてこの新しい &lt;q&gt;&lt;abbr title="Transmission Control Protocol over Internet Protocol"&gt;TCP/IP&lt;/abbr&gt;&lt;/q&gt; プロトコルに変換されるようになりました。私達の知るインターネットが、ついに到来したのです。&lt;/p&gt;

&lt;h2 id="webcreation"&gt;World Wide Web の創成&lt;/h2&gt;

&lt;p&gt;インターネット上の情報検索システムとして、&lt;a href="http://en.wikipedia.org/wiki/Gopher_%28protocol%29"&gt;Gopher&lt;/a&gt; というものが1990年代初頭に使われていました。Gopher は、ファイルへのリンクを含むメニューを提供する仕組みで、リンク先のファイルにはコンピューター上のリソースはもちろん、別のメニューを含むことができました。このメニューという概念により、コンピューターとインターネットの境界を越えて、他のシステム内のメニューを取得することができたのです。Gopher は、学内の情報を提供する手段を探していた大学や、文書の保管や管理を中央集権的に行いたいという大きな組織にとても人気でした。&lt;/p&gt;

&lt;p&gt;さて、Gopher はミネソタ大学により作られたのですが、1993年2月に、彼らは Gopher サーバーの実装に対してライセンス料を取ると発表しました。その結果、多くの組織が Gopher の代替となる仕組みを探し始めることになりました。&lt;/p&gt;

&lt;p&gt;そんな Gopher を代替しうる技術は、スイスの欧州原子核研究機構 (CERN) にありました。当時 CERN の研究員であった Tim Berners-Lee が、テキスト内のリンクを通じ文書から文書を渡ることのできる情報管理システムについて研究していたのです。彼は、この文書（ハイパーテキストと呼ばれていました）を公開するサーバーと、文書を読むためのソフトウェアを開発しました。そして、&lt;q&gt;WorldWideWeb&lt;/q&gt; と名づけられたそのソフトウェアは、1991年に公開されました。しかし、その爆発的な普及と Gopher の置き換えが起こるまでには、まだ2つほど語らなければいけない出来事があります。&lt;/p&gt;

&lt;p&gt;1993年4月13日、CERN は WorldWideWeb のソースコードをパブリックドメインとして公開しました。どういうことかというと、誰も料金を払う必要なくこのソフトウェアを利用でき、また開発できるようになったのです。&lt;/p&gt;

&lt;p&gt;また同年、米国立スーパーコンピュータ応用研究所 (NCSA) が、Gopher クライアントと Web ブラウザーを合体させたプログラム、Mosaic をリリースしました。Mosaic は当初 Unix 端末のみの対応で、配布もソースコードのみでしたが、1993年12月に Apple Macintosh や Microsoft Windows でも動作する Mosaic がインストーラー付きでリリースされました。Mosaic はたちまち人気となり、それに連なり Web の人気も高まりました。&lt;/p&gt;

&lt;p&gt;以降、Web ブラウザーの数は飛躍的に増加しました。ブラウザーの多くは、大学や企業による研究プロジェクトの成果として公開されたものでした。Opera もそのひとつで、ノルウェーの通信会社 Telenor が1994年に公開したものがはじまりです。&lt;/p&gt;

&lt;h3 id="browserwars"&gt;&lt;q&gt;ブラウザー戦争&lt;/q&gt;の勃発&lt;/h3&gt;

&lt;p&gt;Web の認知は、商業的な関心ももたらしました。Mark Andreessen は NCSA を離れ、Jim Clark と共同で Mosaic Communications を設立 (後に Netscape Communications Corporation へと改称) し、後に Netscape Navigator と呼ばれる Web ブラウザーの開発に乗り出しました。Netscape Navigator のバージョン1.0は、1994年12月にリリースされました。&lt;/p&gt;

&lt;p&gt;一方で、NCSA の営利部門である Spyglass Inc.は、Mosaic の技術を Microsoft にライセンス供与し、Micorsoft はそれを基に Internet Explorer を開発しました。Internet Explorer 1.0は、1995年8月にリリースされました。&lt;/p&gt;

&lt;p&gt;すぐに、市場で優位に立つための競争が始まりました。Netscape と Microsoft は開発者を惹きつけるために、機能の拡張を行ったのです。これは&lt;q&gt;ブラウザー戦争&lt;/q&gt;と呼ばれました。一方 Opera はこの競争のなか、小さいながらも着実にその存在を維持し、Web 標準への対応や、Web 標準の発明を可能な限り行っていました。&lt;/p&gt;

&lt;h2 id="comingofstandards"&gt;Web 標準の到来&lt;/h2&gt;

&lt;p&gt;ブラウザー戦争のさなか、Microsoft と Netscape は新しい機能の実装に躍起になっており、既にサポートしている機能のバグを修正することを疎かにしていました。彼らはまた、プロプライエタリな機能の追加もたくさん行われました。さらには競争のために、他のブラウザーで実装されている機能を互換性のないやり方で実装することも行っていたのです。&lt;/p&gt;

&lt;p&gt;当時の開発者は Web サイトを構築する際に、こんな混乱した状況に対処しなければいけなかったのです。二大ブラウザーに対応させるために、同じ内容の Web サイトを2つ構築することもありました。または、どちらかのブラウザーにだけ対応させ、もう一方のユーザーを蚊帳の外に置くといったことも起こりました。こんなひどい状況でしたから、開発者のうっぷんは堪りにたまっていました。&lt;/p&gt;

&lt;h3 id="w3cformation"&gt;W3C の設立&lt;/h3&gt;

&lt;p&gt;1994年に、Tim Berners-Lee は CERN、DARPA (ARPA より改称)、欧州委員会の支援を受け、マサチューセッツ工科大学に World Wide Web Consortium (W3C) を設立しました。W3Cのミッションは、Web を構築する技術やプロトコルの標準化を行い、世界中の人に可能な限りWeb上の情報を提供することです。&lt;/p&gt;

&lt;p&gt;設立してから数年で、W3C はいくつもの&lt;q&gt;勧告&lt;/q&gt;と呼ばれる仕様を公開しました。HTML 4.0、PNG 画像フォーマット、CSS level 1、CSS level 2などが挙げられます。&lt;/p&gt;

&lt;p&gt;しかし、W3C は勧告を強制するといったことを行う団体ではありません。なので、製造側は自分の製品をW3Cの仕様に準拠させたいときにだけ利用すればいいわけです。しかしながら、W3C の仕様に準拠することに、実質的な価値はありません。ほとんどのユーザーがW3Cを知りませんし、気にもしないからです。&lt;/p&gt;

&lt;p&gt;ですから、この&lt;q&gt;ブラウザー戦争&lt;/q&gt;が落ち着くことはありませんでした。&lt;/p&gt;

&lt;h3 id="webstandardsproject"&gt;Web Standards Project&lt;/h3&gt;

&lt;p&gt;1998年には、ブラウザー市場がすでに Internet Explorer 4と Netscape Navigator 4に支配されていました。そんな中、プロプライエタリな機能であるダイナミック HTML を実装した、Internet Explorer 5のベータ版が公開されたのです。これにより、Web 開発者は&lt;em&gt;異なる&lt;/em&gt; JavaScript の書き方を、5つも学ばなければならなくなったのです。&lt;/p&gt;

&lt;p&gt;このことが、数人の Web 開発者・デザイナーを立ち上がらせました。彼らは &lt;q&gt;Web Standards Project&lt;/q&gt; (WaSP) と名乗り、W3C の仕様を「勧告」ではなく「標準」と呼びはじめたのです。そうすることで Microsoft や Netscape を説得し、仕様をサポートさせられるだろうと彼らは考えたのです。&lt;/p&gt;

&lt;p&gt;活動への呼びかけは、&lt;q&gt;roadblock&lt;/q&gt; と呼ばれる古くからある広告手法が使われました。Roadblock は、企業が広告を同じ時間にすべてのチャンネルで宣伝するもので、視聴者がチャンネルを変えても同じ広告を見てしまうというものでした。WaSP もこれに倣い、builder.com、Wired online など、Web 開発を対象としたサイトや多くの参加者がいるメーリングリストに向け、記事を同時に投稿したのです。&lt;/p&gt;

&lt;p&gt;他にも、W3C (または他の標準化団体) に参加を考えている企業のうち、&lt;em&gt;加入の目的であったはずの&lt;/em&gt;基本の理解ではなく、新しい機能の開発ばかりに目を取られてしまったものをひやかす事も行っていました。基本をおろそかにすることは、正しいスタートではないと考えていたからです。&lt;/p&gt;

&lt;p&gt;あまり良い印象を持たないかもしれませんが、WaSP は何も批判だけしていたわけではありません。助けてもいたのです。たとえば、7人のメンバーは &lt;q&gt;CSS Samurai&lt;/q&gt; を組織し、Opera や Internet Explorer の CSS サポートにおける、10の大きな問題を指摘しました（Opera はその後問題を修正しましたが、Internet Explorer が修正を行うことはありませんでした。）&lt;/p&gt;

&lt;h3 id="riseofstandards"&gt;Web 標準の高まり&lt;/h3&gt;

&lt;p&gt;2000年に、Microsoft は Macintosh 版の Internet Explorer 5をリリースしました。これは活気的な出来事でした。なぜなら、このバージョンはW3C勧告を充分な水準でサポートしており、また Mac OS のデフォルトブラウザーだったからです。Macintosh 版の Internet Explorer の Web 標準サポートは、Opera の優れた CSS、HTML サポートとともに、とても肯定的に受け入れられました。Web 開発者やデザイナーが、Web 標準によるデザインをはじめて心地よいと感じた瞬間だったのです。&lt;/p&gt;

&lt;p&gt;そこで、WaSP は Netscape に、Netscape Navigator 5.0が Web 標準を充分にサポートするまでリリースを延期しようと Netscape を説得しました（そしてこの行動は、後に Firefox となる人気ブラウザーの誕生につながりました）。WaSP はまた、&lt;q&gt;Dreamweaver Task Force&lt;/q&gt; という、Macromedia の Dreamweaver を Web 標準に準拠させるタスクフォースも設立しました。&lt;/p&gt;

&lt;p&gt;2001年のはじめに、人気の Web 開発サイト &lt;q&gt;A List Apart&lt;/q&gt; がリデザインされました。このリデザインについて、手法や理由を説明した記事が公開されているのですが、その中にこんな一節があります。&lt;/p&gt;

&lt;blockquote cite="http://www.alistapart.com/articles/tohell"&gt;
&lt;p&gt;In six months, a year, or two years at most, all sites will be designed with these standards. […] We can watch our skills grow obsolete, or start learning standards-based techniques now.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p class="note"&gt;訳: 半年か一年、いや二年後には全てのサイトが、これらの Web 標準を利用してデザインされるだろう。[…] いま私達にできることは、今までのやり方が古くなるのをただ見ているか、新しい Web 標準ベースな技術を学び始めるかのどちらかだ。&lt;/p&gt;

&lt;p&gt;この予想はすこし前向きすぎました。2008年になっても、全てのサイトがWeb標準で作られている訳ではないからです。しかし、この言葉には多くの人が耳を傾けていました。古いブラウザーはシェアを落とし、そして Wired magazine と ESPN という二つの大きなサイトが、それぞれ2002年と2003年に、Web 標準によってリデザインされたのです。彼らは Web 標準や新しい技術を支持する第一人者となりました。&lt;/p&gt;

&lt;p&gt;さらに、2003年に Dave Shea が &lt;q&gt;CSS Zen Garden&lt;/q&gt; というサイトを公開しました。何よりも Web プロフェッショナルに大きな影響を与えたのが、このサイトでした。なぜなら、CSS Zen Garden は、中身が全く同じページでも、CSS ひとつでデザイン全て変更できることを端的に表現したからです。&lt;/p&gt;

&lt;p&gt;それ以来、Web 標準は Web 開発コミュニティで当たり前の存在になりました。そしてこのコースは、Web 標準によるデザイン手法の基礎を知ることのできる、素晴らしい資料になっています。このコースを進めていけば大手サイトのように、きれいで、意味的で、アクセシブルで、そして Web 標準に準拠するWebサイトを作れるようになるのです。&lt;/p&gt;

&lt;h2 id="summary"&gt;まとめ&lt;/h2&gt;

&lt;p&gt;この記事では、宇宙開発競争が現在のインターネットを生み出したこと、Tim Berners-Lee が世代を超えたハイパーテキストを定義したこと、二つの企業が商業的な関心から、歴史に残る開発者の反発を生んだことを説明しました。&lt;q&gt;Web 標準&lt;/q&gt;という言葉は Web プロフェッショナルの間で広く使われていますが、W3C の中でも使われています（彼らのページにもこの単語が出ていますね）。ですので、これが私達が教えること、つまり Web サイトを構築する&lt;em&gt;標準的な&lt;/em&gt;やり方になります。&lt;/p&gt;

&lt;h2 id="furtherreading"&gt;関連資料&lt;/h2&gt;

&lt;p&gt;もっと知りたいと思った方は、次のサイトを読んでみましょう。&lt;/p&gt;
&lt;p class="note"&gt;訳注：以下のリンクは全て英語で書かれています。&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/History_of_the_Internet"&gt;The history of the Internet (wikipedia)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/History_of_the_World_Wide_Web"&gt;The history of the World Wide Web (wikipedia)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.w3.org/Consortium/history"&gt;The history of the W3C&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://webstandards.org/"&gt;The Web Standards Project&lt;/a&gt;, and their &lt;a href="http://www.webstandards.org/about/history/"&gt;history&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.alistapart.com/"&gt;A List Apart&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.csszengarden.com/"&gt;CSS Zen Garden&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="exercisequestions"&gt;練習問題&lt;/h2&gt;

&lt;p&gt;もっと調べたいと思った方は、次の問題に答えてみましょう。&lt;/p&gt;
    
&lt;ul&gt;
  &lt;li&gt;Windows、Mac OS X、Linux には、どんなブラウザーがありますか？&lt;/li&gt;
  &lt;li&gt;各ブラウザー利用者の割合はどのようになっていますか？&lt;/li&gt;
  &lt;li&gt;モバイル端末がWebにアクセスする際、どんなブラウザーを利用しますか？&lt;/li&gt;
  &lt;li&gt;W3C が公開した &lt;q&gt;Web 標準&lt;/q&gt;の数はどれくらいになりますか？そして、ブラウザーベンダーによって広く実装されているものはどれですか？&lt;/li&gt;
&lt;/ul&gt;

&lt;ul class="seriesNav"&gt;
&lt;li class="prev"&gt;&lt;a rel="start" href="http://dev.opera.com/articles/view/1-introduction-to-the-web-standards-cur-ja/"&gt;前の記事: Web 標準カリキュラムの紹介&lt;/a&gt;&lt;/li&gt;
&lt;li class="next"&gt;&lt;a rel="next" href="http://dev.opera.com/articles/view/3-how-does-the-internet-work-ja/"&gt;次の記事: インターネットのしくみ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel="index" href="http://dev.opera.com/articles/view/1-introduction-to-the-web-standards-cur-ja/#toc"&gt;カリキュラムの目次へ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;著者紹介&lt;/h2&gt;

&lt;div class="right"&gt;
&lt;img alt="著者 Mark Norman Francis の写真" src="http://dev.opera.com/articles/view/2-the-history-of-the-internet-and-the-w/norm.jpg" /&gt;
&lt;p class="comment"&gt;Photo credit: &lt;a href="http://flickr.com/photos/andybudd/98405468/"&gt;Andy Budd&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Mark Norman Francis は Web の発明以前より、インターネットを利用していました。彼は Yahoo! で Front End Architect として、Web 開発におけるベストプラクティス、コーディング標準、そして品質の定義を世界的な規模で行った経験があります。&lt;/p&gt;

&lt;p&gt;Yahoo! 以前の彼は、Formula One Management、Purple Interactive、City University にて Web 開発、バックエンド CGI プログラミング、システムアーキテクチャなど、さまざまな仕事を行っています。彼は &lt;a href="http://marknormanfrancis.com/"&gt;http://marknormanfrancis.com/&lt;/a&gt; にて、ブログのようなものを書いています。&lt;/p&gt;

&lt;h2&gt;翻訳者について&lt;/h2&gt;

&lt;img alt="翻訳者矢倉眞隆の写真" src="mitsue-myakura.jpg" class="right" /&gt;

&lt;h3&gt;矢倉 眞隆 (Masataka Yakura)&lt;/h3&gt;
&lt;p&gt;1984年生まれ。株式会社ミツエーリンクスにて、社内の品質改善活動や Web 標準 の普及啓蒙を行っている。W3C HTML WG メンバー。&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://www.mitsue.co.jp/"&gt;株式会社 ミツエーリンクス&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;
1990年創業。大規模な Web サイト開発を得意とするインフォメーション・インテ グレータ。自社コンテンツの &lt;a href="http://standards.mitsue.co.jp/"&gt;Web 標準 Blog&lt;/a&gt; や&lt;a href="http://accessibility.mitsue.co.jp/"&gt;アクセシビリティ Blog&lt;/a&gt; より、Web フロントエンド技術に関するさまざまな情報を発信中。&lt;/p&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevOperaFullFeed/~4/aTXiTRCygvk" height="1" width="1"/&gt;</description>
<feedburner:origLink>http://dev.opera.com/articles/view/796</feedburner:origLink></item>
<item rdf:about="http://dev.opera.com/articles/view/801">
<creator>Masataka Yakura</creator>
<dc:date>2009-10-20T03:06:07Z</dc:date>
<link>http://feedproxy.google.com/~r/DevOperaFullFeed/~3/4CsdoYOddAw/801</link>
<title>1: Web 標準カリキュラムの紹介</title>
<description>&lt;div class="article"&gt;&lt;ul class="seriesNav"&gt;
&lt;li class="next"&gt;&lt;a rel="next" href="http://dev.opera.com/articles/view/2-the-history-of-the-internet-and-the-w-ja/"&gt;次の記事: インターネットと Web の歴史、そして Web 標準の進化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel="index" href="http://dev.opera.com/articles/view/1-introduction-to-the-web-standards-cur-ja/#toc"&gt;カリキュラムの目次へ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;はじめに&lt;/h2&gt;

&lt;p&gt;私には、ある夢がありました。&lt;/p&gt;

&lt;p&gt;過去8、 9年にわたり、私は教育に関する仕事に力を注いでいました。あるときは技術書を執筆し、人がその技術で何かかっこいいものを作る手助けをしました。勤務先に新しく入ってきた人の訓練を行うこともありました。また、利用者の助けになるよう、Opera のソフトウェアについてチュートリアルの執筆・編集も行いました。&lt;/p&gt;

&lt;p&gt;私は Web についても熱意をもっています。その中でも、オープン Web 標準というものをとても信じています。そして、Web をより良いものとするために私に何ができるのだろうと考えたとき、はじめに言った教育というトピックに立ち返るのです。&lt;/p&gt;

&lt;p&gt;「教育」といっても、いろいろあるでしょう。他人を尊敬し、お互いが協力しあう方法を教えることかもしれません。あるいは、デバイスやプラットフォームを越えて機能し、また障害を持つ人に対してアクセシブルな Web サイトを作る方法を教えることかもしれません。このうち、Web 標準について当てはまるのは後者です。というわけで私は、今日そして将来の Web のために、Web標準を採用するサイトを増やす手助けに注力しようと決意しました。&lt;/p&gt;

&lt;p&gt;決意してからしばらくの間は、思いが私の頭の中だけに留まっていましたが、Opera で働く機会を得ることで実現することができました。仕事として価値を見いだしてくれた Opera に、とても感謝しています！ついに、夢のひとつがかなったのです。&lt;/p&gt;

&lt;p&gt;というわけで、この記事では過去数か月にわたる努力の結晶である&lt;strong&gt; Web 標準カリキュラム&lt;/strong&gt;について紹介したいと思います。このカリキュラムは、私を含めたくさんの方が執筆した、Web デザイン・Web 開発の土台となる知識を提供するコース資料です。カリキュラムはほぼすべての方を対象としています。お金は必要ありませんし、資料はアクセシブルです。また、事前知識も必要としません。&lt;/p&gt;

&lt;p&gt;私はこのカリキュラムを大学で利用してほしいと考えています。なぜなら、Web標準に関する教育資料や指標は、多くの大学で不足しているからです。私は多くの学生から、彼らが Web 標準で作成した課題が減点されるという話を聞きました。これはなぜかというと、とても古い知識を基に採点が行われているからです。一方で、Web 関連の職種で募集をかける雇用者からは、面接を受けに来た学生が Web 開発の実情をまったく知らないといった嘆きも聞いています。&lt;/p&gt;

&lt;p&gt;もしあなたが、望ましい方法でWeb標準を教える先進的な大学に居たら、ぜひ&lt;a href="#contact"&gt;連絡してください&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;さて、この記事は次のような構成になっています。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#webstandards"&gt;なぜ、Web 標準なのか？&lt;/a&gt; — Web 標準を利用することの利点はもちろんのこと、一部で受け入れられていない現状とその理由、そして、このコースがどのように対処しようとしているのかを簡単に述べようと思います。&lt;/li&gt;
&lt;li&gt;&lt;a href="#structure"&gt;コースの構成&lt;/a&gt; — 名前のとおり、コースがどのように構成されているのか、また教育担当者がどのように資料を利用すると効果的かを説明します。&lt;/li&gt;
&lt;li&gt;&lt;a href="#who"&gt;このコースを利用すべき人は誰？&lt;/a&gt; — 「誰もが (anyone)」と書くことがあるのですが、それが具体的にどういった意味なのかを説明します。&lt;/li&gt;
&lt;li&gt;&lt;a href="#toc"&gt;カリキュラムの目次&lt;/a&gt; — 「おしゃべりはもう勘弁。早く学びたい。」という方はこちらをクリックしましょう。目次にスキップできます。&lt;/li&gt;
&lt;li&gt;&lt;a href="#acks"&gt;謝辞&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#contact"&gt;連絡先&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="webstandards"&gt;なぜ、Web 標準なのか？&lt;/h2&gt;

&lt;p&gt;Web 標準を Web デザイン / Web 開発に取り入れることは、どう素晴らしいのでしょうか。4番の記事に詳しく書かれていますが、ここでも簡単に説明しておくことにしましょう。&lt;/p&gt;
&lt;p&gt;Web 標準を利用することで、次のような恩典が与えられます。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;コーディングの効率化&lt;/strong&gt;: このコースを進めていくと、Web標準に関するベストプラクティスの多くが、コードの再利用に関係していることに気づくと思います。ページの内容 (HTML) 、スタイル情報 (CSS) 、挙動に関する情報 (JavaScript) をそれぞれ分けることで、ファイルサイズを抑えることができ、また情報の再利用が同じコードを書くことなく実現できます。&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;管理の容易さ&lt;/strong&gt;: 効率に関連するのですが、HTML をまず書き、あとで必要な部分にだけスタイルと挙動を class や関数を利用し与えるというやり方は、サイトの管理を容易にします。もしあとでスタイルや挙動を変更する必要が生じても、該当する一部分を編集するだけでWebサイト全体に反映されるからです。すべての HTML 文書をいちいち変更する必要はありません。&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;アクセシビリティ&lt;/strong&gt;: Web における重要課題のひとつに、&lt;em&gt;置かれている環境を問わず、すべての人に対し Web サイトをアクセシブルにする&lt;/em&gt;というものがあります。たとえば、視覚障害や運動障害 (手を自由に動かせないなど、運動機能に制限のある状態) を持つ方が、不自由なく Web サイトを利用できるようにすることが挙げられます。大変そうに感じるかもしれませんが、Web 標準とベストプラクティスに従うことで、余計な労力を割くことなく、多くの方に対してアクセシブルな Web サイトにすることが可能です。&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;デバイスの互換性&lt;/strong&gt;: これは、Windows、Mac、Linux といったプラットフォームだけではなく、携帯電話やテレビ、ゲーム機など、別のブラウジングデバイスにおいてもWebサイトを機能させることを意図しています。これらのデバイスには、画面の大きさやプロセッサーの性能、操作手法に制限がありますが、これもアクセシビリティと同様に、Web 標準とベストプラクティスを利用することで多くのデバイスで機能する Web サイトにできるのです。いまや、携帯電話は PC よりも急速に普及しており、またそれらの多くがインターネットに接続できます。それなのに、このマーケットを見過ごすことを、あなたやあなたのクライアントが許すでしょうか？(モバイル Web 開発については、&lt;a href="http://dev.opera.com/articles/mobile/"&gt;dev.opera.com&lt;/a&gt;に掲載されているモバイル関連の記事もご覧ください。)&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Web クローラー/検索エンジン&lt;/strong&gt;: いわゆる&lt;em&gt;検索エンジン最適化 (SEO)&lt;/em&gt;と呼ばれるものです。ちょっと詳しく説明すると、Web を巡回しサイトをインデックスに登録する Web クローラーというものに対して、Web サイトを可能な限り可視化することで、&lt;a href="http://www.google.com"&gt;Google&lt;/a&gt; や他の検索ランキングで上位になる方法を表します。SEO にはいろいろな術があるのですが (詳しくは &lt;a href="http://dev.opera.com/articles/view/intelligent-site-structure-for-better-se/"&gt;Intelligent site structure for better SEO!&lt;/a&gt; や &lt;a href="http://dev.opera.com/articles/view/semantic-html-and-search-engine-optimiza/"&gt;Semantic HTML and Search Engine Optimization&lt;/a&gt; などの SEO 関連記事をご覧ください)、これについても Web 標準を利用することで、Google や Yahoo! に対し Web サイトをより可視化することができ、ビジネスに良い影響をもたらすのです。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Web 標準にはこのような利点があります。しかし一方で、Web にあるサイトのほとんどが未だWeb標準に従ったものではありません。さらに、Web 開発者の多くもまた、時代遅れでかつ良くない手法を利用し続けているのです。&lt;/p&gt;

&lt;p&gt;「どうして？」と思った方がいるかもしれません。でも、これにはいくつかの理由があるのです。不十分な教育、会社のポリシー、学ばなくても稼げることによる学習意欲の低下、Web 標準の難しさ、Web ブラウザーの Web 標準対応状況といったことを理由に、言い訳をする人がいるのです。&lt;/p&gt;
&lt;p&gt;では、一つずつ詳しくその理由を考え、さらに反論してみましょう。Web 標準を学ばない/取り入れないことに言い訳ができないようにするのです。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;不十分な教育&lt;/strong&gt;: これがこのコースの存在理由でもありますね。多くの大学が、Web 関連のコースで Web 標準を教えることはありませんし、また多くのカリキュラムが、時代遅れな手法を今でも解説しています。変えようとしても、お役所的な手続きがありますからとても難しいのです。書籍やトレーニングなどもありますが、高くつきます。しかし、ちょっと待ってください。そのための Web 標準カリキュラムです。このコースは無料ですし、Web 標準の教育について大学などにプッシュも行っています。言い訳はできませんよ。&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;会社のポリシー&lt;/strong&gt;: いくつかの企業や研究所のWebサイトが時代遅れなことについて、疑いの余地はありません。そういったところでは、職員に時代遅れのブラウザーの仕様を義務付けるポリシーがあるかもしれません。しかし、状況は改善されています。どのように Web サイトを作り変えていけばいいのかを説明するコースも無料で存在していますし、今こそ悪い習慣を改めるべきなのです。Web サイトを Web 標準というモダンなつくりにすることにより、古いブラウザーでは見栄えが悪くなることがあります。そうなると、内部で利用するブラウザーもアップグレードしようという動きがでてくるでしょう (もちろん、古いブラウザーでも新しい Web サイトは最低限機能しなければなりませんが)。また、企業は顧客に対してもブラウザーのアップグレードを進めるべきです。Web 標準なサイトにすることにより、検索結果のランク向上やアクセシビリティの確保、多様なデバイスに対応できるなど、ビジネスメリットもあります。それを無視するつもりでしょうか？&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;「勉強する必要なんてないから」&lt;/strong&gt;: 「時代遅れなやり方でも給料はもらえているし、なんで新しいやり方に悩まされる必要があるんだい？」なんて言う人がいることを私は知っています。でも、先ほど説明したとおり、Web 標準によるやり方は効率がよく、また書くことも管理することも容易なのです。また、モダンなコードはアクセシブルですし、デバイスを限定することもありません。なんだか、わくわくしてきませんか？さらに、新しいことを学べば、自分のスキルセットをこれからのキャリアにも生かせるでしょうし、もっとお金を稼げるようになるかもしれません。それに今日の企業は、Web 標準のスキルがある人を要求しているんですよ。&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;「難しいんだよ」&lt;/strong&gt;: まったくもう。ちょっとでいいので、コースを進めてみてください。Web 標準の基礎を習得することが難しくないことを理解できると思いますから。これは特定の人に限ったことではありません。Web デザイン / Web 開発の初心者であっても、またはスキルを磨くため新しく Web 標準を学ぼうとしている Web 開発者であっても、同じように感じるはずです。Web 標準は時代遅れなやり方と同じくらいの難易度ですし、そこまで難しいわけではありません。しかし、そのような古いやり方に比べて、多くの利点があるんです。&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;ブラウザーの Web 標準サポート&lt;/strong&gt;: ブラウザーの Web 標準に関するサポートは、昔は本当にバラバラでした。ですから、Web サイトのクロスブラウザー対応は悪夢のようなものでした。しかし最近はそうでもありません。新しいブラウザーは充分に Web 標準をサポートしています。対応度合いの低い古いブラウザーに対してはまだ配慮が必要ですが、現在のベストプラクティスを使えば、古いブラウザーの利用者に対しても理にかなったユーザー体験を提供できるのです。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;いかがでしょう。ご覧のとおり、Web 標準を取り入れないことへの言い訳はもう通じません。もしあなたが初心者であれば古いやり方を忘れる必要もないので、ペストプラクティスを最初から学べます。&lt;/p&gt;

&lt;div class="note"&gt;
&lt;p&gt;「古いやり方」などとぼやかし、具体的な説明をしていませんね。私達は、このコースでそれらを説明することは考えていません。むしろ、そのようなことを知ることなく、ただ正しい道を歩めばいいと思っています。&lt;/p&gt;
&lt;p&gt;しかしながら、一体全体なんのことを言っているのか、気になって仕方がない人もいるでしょう。というわけで、ここでざっくりと説明しましょう。&lt;/p&gt;

&lt;p&gt;その昔、Web サイトは表 (table) を利用してページのレイアウトを行っていました。画像やテキストを別々のセルにあてがうという使い方ですが、これは表の適切な使い方ではありません。また、マークアップが過剰なものになってしまいます。レイアウト関連の手法にはスペーサー GIF と呼ばれる、透明な画像でページ内の要素を厳密に調整するものがありした。しかしこちらも表と同様に、画像の適切な使い方ではありませんし、画像を過剰に使うことになります。&lt;/p&gt;

&lt;p&gt;JavaScript で動的なメニューを実現するページもありました。しかしこれは、JavaScript を無効にした環境では動作しませんし、スクリーンリーダーを利用する視覚障害者を混乱させてしまいます。また、特定のブラウザーでしか動かないといったことも起こります。&lt;/p&gt;

&lt;p&gt;他にも、&lt;code&gt;&amp;lt;font&amp;gt;&lt;/code&gt; タグを利用し、スタイル情報を HTML 文書内に直接埋め込むものもありました。管理性は最悪で、マークアップも過剰になります。&lt;/p&gt;

&lt;p&gt;これはほんの一部で、他にも Web 開発にとって良くない手法がいっぱいあります。そして、何より残念なのが「その昔」と書いている一方で、これらの手法が未だ多くの人に使われていることなのです。&lt;/p&gt;

&lt;p&gt;Web 開発というものは、どんなに良くても面倒なものです。しかし、これらの悪いやり方を使い続けても、事態は悪くなる一方です。ですから、このコースでも説明するとおり、Web 標準とベストプラクティスを利用することが、一番良い方法なのです。&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id="structure"&gt;コースの構成&lt;/h2&gt;

&lt;p&gt;このコースは、数多くの記事から構成されています。基本コースで50本以上の記事があり、各記事は数千ワードほどの長さになります。個々の記事は特定の内容について取り上げており、必要に応じて、その背景や重要な理論、実践的な例やチュートリアル、例題などが提供されます。&lt;/p&gt;

&lt;p&gt;コースを教えるもっとも論理的な方法は、あなたの受け持つ講義の回数にあわせて、記事を割り振ることです。講義でカバーする内容は、事前に生徒に関連する記事を読ませ予習させます。そして講義では、記事中の実践的な例をひとつずつ見ていきます。講義の後は、復習として生徒に例題を解かせます。&lt;/p&gt;

&lt;p&gt;事前に記事を読ませてさえいれば、ひとつの講義にかける時間は1時間程度で充分カバーできると考えています。ですから、コース全体にかかる講義の時間は50時間ほど、そして予習にかける時間も50時間ほどになるでしょう。&lt;/p&gt;

&lt;p&gt;もちろん、講義にかけられる時間や何をカバーするのかなど、考えなければいけないこともあります。しかし、実践することが重要です。&lt;/p&gt;

&lt;h2 id="who"&gt;このコースを利用すべき人は誰？&lt;/h2&gt;

&lt;p&gt;このカリキュラムは、数多くの記事から構成されるWeb標準に関するコース資料で、Web 標準なデザイン手法を一から学びたいという人を対象としています。&lt;/p&gt;

&lt;p&gt;Web サイトをただ閲覧するくらいの人でも、資料を読めば CSS や HTML の知識を充分に持ち、加えて基本的な JavaScript を理解できることを目的に、このコースは作られています。それだけの知識があれば、就職や転職に自信をもって挑むことができるでしょうから (もっとも、経験について教えることはできませんが)。&lt;/p&gt;

&lt;p&gt;で、具体的にどんな人なのでしょう？私はこのカリキュラムが、Web デザインの「よいやり方」を学びたいという人に役立ってほしいと思っています。たとえば、次のような人たちです。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;大学やカレッジの生徒/教員&lt;/strong&gt;: すでに書きましたが、このカリキュラムは独自のコース資料をつくるにも、コースの資料として一部を利用するにも理想的なものになっています。もしあなたが Web 関連のコースを受講している学生であれば、このカリキュラムを補足資料として使うべきです。そして、先生にもこの資料を使うよう働きかけてください！あなたが先生や講師である場合、講義で利用するテクニックがベストプラクティスであるかどうかを確かめる資料として、このカリキュラムを利用することをおすすめします。&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;高校生やもっと若い学生&lt;/strong&gt;: このコースは大人の人を主な対象として書いていますが、それは別に、若い学生さんに恩恵がないというわけではありません。カリキュラムに目を通して、どのように進められるかを確かめてみてください。&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Web デザイナーや開発者&lt;/strong&gt;: Web 標準やベストプラクティスを利用していない人、手ごろなリファレンスを利用して知識を磨く人など、世の中にはさまざまなタイプの Web 開発者やデザイナーがいます。前者の方に対して私は、このカリキュラムをWeb標準が簡単で価値のあることを理解するチャンスとして授けたいと思います。後者の方には、このカリキュラムをさまざまなことに役立ててほしいと思っています。たとえば、人を助けたり、スキルを磨いたり、難しいことを思い出すためのリファレンスとして使うことができるでしょう。また、上司やクライアントに対して、アクセシビリティには価値があることを説得するための材料としても利用できるでしょう。&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;企業内の教育担当者&lt;/strong&gt;: このカリキュラムは無料ですから、安価なトレーニング資料としてとても理想的です。&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;そのほかの方&lt;/strong&gt;: もしあなたがちょっと Web デザインや Web 開発に興味を持っているのであれば、知見を広げるための資料として使ってくれたらと思っています。なんたって、このカリキュラムは無料ですし。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;このコースにお金を払うことを、私は期待していません。このコースはクリエイティブ・コモンズ・ライセンスのもとで提供されており、適切な表示 (Attribution) さえあれば、だれもが自由に利用することができるようになっています。&lt;/p&gt;

&lt;h2 id="toc"&gt;Web標準カリキュラム：目次&lt;/h2&gt;

&lt;h3&gt;はじめに&lt;/h3&gt;

&lt;ol start="1"&gt;
&lt;li&gt;Web 標準カリキュラムの紹介 (Chris Mills 著) — 今あなたが読んでいる記事です。&lt;/li&gt;
&lt;/ol&gt;

&lt;p class="note"&gt;翻訳のお知らせ: &lt;a href="http://dev.opera.com/articles/view/web-standards-curriculum-translations/"&gt;Web 標準カリキュラムの翻訳&lt;/a&gt;も行われています。&lt;/p&gt;

&lt;p class="note"&gt;訳注: カリキュラムの原典は英語版になります。これはその日本語訳です。&lt;/p&gt;

&lt;h3&gt;Web 標準の世界へのいざない&lt;/h3&gt;

&lt;ol start="2"&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/2-the-history-of-the-internet-and-the-w-ja/"&gt;インターネットと Web の歴史、そして Web 標準の進化&lt;/a&gt; (Mark Norman Francis 著)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/3-how-does-the-internet-work-ja/"&gt;インターネットのしくみ&lt;/a&gt; (Jonathan Lane 著)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/4-the-web-standards-model-html-css-a/"&gt;The Web standards model—HTML, CSS and JavaScript&lt;/a&gt;, by Jonathan Lane.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/5-web-standards-beautiful-dream-bu/"&gt;Beautiful dream, but what’s the reality?&lt;/a&gt;, by Jonathan Lane.&lt;/li&gt;
&lt;/ol&gt;

&lt;p class="note"&gt;訳注: 以降の記事については、現在翻訳を行っている最中です。&lt;/p&gt;

&lt;h3&gt;Web デザインの基本理念&lt;/h3&gt;

&lt;p&gt;このセクションでは、コードやマークアップの詳細は扱いません。ここでは、画像の作成やコーディングの前に行うWebデザインプロセスについて、また、IA やナビゲーション、ユーザビリティなどの概念について紹介します。&lt;/p&gt;

&lt;ol start="6"&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/6-information-architecture-planning-o/"&gt;Information Architecture—planning out a web site&lt;/a&gt;, by Jonathan Lane.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/7-what-does-a-good-web-page-need/"&gt;What does a good web page need?&lt;/a&gt;, by Mark Norman Francis.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/8-color-theory/"&gt;Colour Theory&lt;/a&gt;, by Linda Goin.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/9-building-up-a-site-wireframe/"&gt;Building up a site wireframe&lt;/a&gt;, by Linda Goin.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/10-colour-schemes-and-design-mockups/"&gt;Colour schemes and design mockups&lt;/a&gt;, by Linda Goin.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/11-typography-on-the-web/"&gt;Typography on the web&lt;/a&gt;, by Paul Haine.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;HTML の基礎&lt;/h3&gt;

&lt;ol start="12"&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/12-the-basics-of-html/"&gt;The basics of HTML&lt;/a&gt;, by Mark Norman Francis.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/13-the-html-head-element/"&gt;The HTML &amp;lt;head&amp;gt; element&lt;/a&gt;, by Christian Heilmann.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/14-choosing-the-right-doctype-for-your/"&gt;Choosing the right doctype for your HTML documents&lt;/a&gt;, by Roger Johansson.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;HTML の中身&lt;/h3&gt;

&lt;ol start="15"&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/15-marking-up-textual-content-in-html/"&gt;Marking up textual content in HTML&lt;/a&gt;, by Mark Norman Francis.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/16-html-lists/"&gt;HTML Lists&lt;/a&gt;, by Ben Buchanan.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/17-images-in-html/"&gt;Images in HTML&lt;/a&gt;, by Christian Heilmann.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/18-html-links-let-s-build-a-web/"&gt;HTML links—let’s build a web!&lt;/a&gt; by Christian Heilmann. &lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/19-html-tables/"&gt;HTML Tables&lt;/a&gt;, by Jen Hanen.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/20-html-forms-the-basics/"&gt;HTML Forms—the basics&lt;/a&gt;, by Jen Hanen.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/21-lesser-known-semantic-elements/"&gt;Lesser–known semantic elements&lt;/a&gt;, by Mark Norman Francis.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/22-generic-containers-8212-the-div-and/"&gt;Generic containers—the div and span elements&lt;/a&gt;, by Mark Norman Francis.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/23-creating-multiple-pages-with-navigat/"&gt;Creating multiple pages with navigation menus&lt;/a&gt;, by Christian Heilmann.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/24-validating-your-html/"&gt;Validating your HTML&lt;/a&gt;, by Mark Norman Francis.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;アクセシビリティ&lt;/h3&gt;

&lt;ol start="25"&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/25-accessibility-basics/"&gt;Accessibility basics&lt;/a&gt;, by Tom Hughes-Croucher.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/26-accessibility-testing/"&gt;Accessibility testing&lt;/a&gt;, by Benjamin Hawkes-Lewis.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;CSS&lt;/h3&gt;

&lt;ol start="27"&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/27-css-basics/"&gt;CSS basics&lt;/a&gt;, by Christian Heilmann.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/28-inheritance-and-cascade/"&gt;Inheritance and Cascade&lt;/a&gt;, by Tommy Olsson.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/29-text-styling-with-css/"&gt;Text styling with CSS&lt;/a&gt;, by Ben Henick.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/30-the-css-layout-model-boxes-border/"&gt;The CSS layout model - boxes, borders, margins, padding&lt;/a&gt;, by Ben Henick.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/31-css-background-images/"&gt;CSS background images&lt;/a&gt;, by Nicole Sullivan.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/32-styling-lists-and-links/"&gt;Styling lists and links&lt;/a&gt;, by Ben Buchanan.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/33-styling-tables/"&gt;Styling tables&lt;/a&gt;, by Ben Buchanan.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/34-styling-forms/"&gt;Styling forms&lt;/a&gt;, by Ben Henick.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/35-floats-and-clearing/"&gt;Floats and clearing&lt;/a&gt;, by Tommy Olsson.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/36-css-static-and-relative-positioning/"&gt;CSS static and relative positioning&lt;/a&gt;, by Tommy Olsson.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/37-css-absolute-and-fixed-positioning/"&gt;CSS absolute and fixed positioning&lt;/a&gt;, by Tommy Olsson.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;CSS の上級コース&lt;/h3&gt;

&lt;ol start="38"&gt;
  &lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/38-headers-footers-columns-templates/"&gt;Headers, footers, columns, and templates&lt;/a&gt;, by Ben Henick&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;JavaScript の基本&lt;/h3&gt;

&lt;ol start="27"&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/27-css-basics/"&gt;CSS basics&lt;/a&gt;, by Christian Heilmann.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/28-inheritance-and-cascade/"&gt;Inheritance and Cascade&lt;/a&gt;, by Tommy Olsson.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/29-text-styling-with-css/"&gt;Text styling with CSS&lt;/a&gt;, by Ben Henick.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/30-the-css-layout-model-boxes-border/"&gt;The CSS layout model - boxes, borders, margins, padding&lt;/a&gt;, by Ben Henick.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/31-css-background-images/"&gt;CSS background images&lt;/a&gt;, by Nicole Sullivan.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/32-styling-lists-and-links/"&gt;Styling lists and links&lt;/a&gt;, by Ben Buchanan.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/33-styling-tables/"&gt;Styling tables&lt;/a&gt;, by Ben Buchanan.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/34-styling-forms/"&gt;Styling forms&lt;/a&gt;, by Ben Henick.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/35-floats-and-clearing/"&gt;Floats and clearing&lt;/a&gt;, by Tommy Olsson.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/36-css-static-and-relative-positioning/"&gt;CSS static and relative positioning&lt;/a&gt;, by Tommy Olsson.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/37-css-absolute-and-fixed-positioning/"&gt;CSS absolute and fixed positioning&lt;/a&gt;, by Tommy Olsson.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;モバイル Web 開発&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/introduction-to-the-mobile-web/"&gt;Mobile 1: Introduction to the mobile web&lt;/a&gt;, by Brian Suda&lt;/li&gt;
&lt;/ol&gt;


&lt;h3&gt;補足記事&lt;/h3&gt;

&lt;h4&gt;マイクロフォーマット&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/introduction-to-hcard/"&gt;Introduction to hCard&lt;/a&gt;, by Christopher Schmitt&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/introduction-to-hcard-part-two-styling/"&gt;Introduction to hCard, Part two: Styling hCards&lt;/a&gt;, by Christopher Schmitt&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/xfn-encoding-extraction-and-visualizat/"&gt;XFN encoding, extraction, and visualizations&lt;/a&gt;, by Brian Suda&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/styling-xfn-and-rel-license-links/"&gt;Styling XFN and rel-license links&lt;/a&gt;, by Christopher Schmitt&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/styling-hreview-microformats/"&gt;Styling hReview Microformats&lt;/a&gt;, by Christopher Schmitt&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/microformat-encoding-and-visualization/  "&gt;Microformat Encoding and Visualization&lt;/a&gt;, by Brian Suda&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;アクセシビリティに関する補足記事&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/introduction-to-wai-aria/"&gt;Introduction to WAI-ARIA&lt;/a&gt;, by Gez Lemon&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/creating-accessible-data-tables/"&gt;Creating accessible data tables&lt;/a&gt;, by Frank Palinkas&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/building-accessible-static-navigation-wi/"&gt;Building Accessible Static Navigation with CSS&lt;/a&gt;, by Frank Palinkas&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;そのほか&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/supplementary-getting-your-content-onli/"&gt;Getting your content online&lt;/a&gt;, by Craig Grannell.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/supplementary-more-about-the-document/"&gt;More about the document &amp;lt;head&amp;gt;&lt;/a&gt;, by Chris Heilmann.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/supplementary-common-html-entities-used/"&gt;Supplementary: Common HTML entities used for typography&lt;/a&gt;, by Ben Henick.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/opera-web-standards-curriculum-glossary/"&gt;The Opera Web Standards Curriculum glossary&lt;/a&gt;, by various authors. This is incomplete, and will be added to as time goes by.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="acks"&gt;謝辞&lt;/h2&gt;

&lt;p&gt;このコースの作成には、本当に多くの方の協力がありました。ここで紹介する方は、皆とても素晴らしい人達ですので、みなさん是非、彼らの講演を聞きに出かけたり、本を買ったり、ブログを読んだりなど、できる限りの応援をしていただけたらと思います。&lt;/p&gt;
&lt;p&gt;彼らに、感謝と敬意をこめて。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;著者&lt;/strong&gt;: 記事の著者である Ben BuchananTom Hughes–Croucher, Mark Norman “Norm” Francis, Linda Goin, Paul Haine, Jen Hanen, Benjamin Hawkes–Lewis, Ben Henick, Christian Heilmann, Roger Johansson, Peter–Paul Koch, Jonathan Lane, Stuart Langridge, Robert Nyman, Tommy Olsson, Greg Schechter, Nicole Sullivan, Mike West, 本当にありがとうございます。あなた達がいなければ、このコースは存在していなかったでしょう。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Opera&lt;/strong&gt;: Jan Standal, David Storey, 私のチームのみんな、そしてこの考えに賛同し、企画を進めてくれた Opera の従業員、どうもありがとうございます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;企業や組織&lt;/strong&gt;: Yahoo (著者の方と、構成やプロモーションに多大な貢献をしてくれた Sophie Major), WaSP (特に Gareth Rushgrove, Stephanie Troeth と Aarron Walter), Britpack, Geekup のみなさん、そしてこのコースに興味をもち、また後押しをしてくれた大学など、多くの企業や組織の強力がありました。とても感謝しています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;貢献者&lt;/strong&gt;: Craig Saila, Sara Dodd, John Allsopp, Roan Lavery, Bruce Lawson, Alan White といった素晴らしい人々に感謝しています。忘れている人がいたら、ごめんなさい。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;読者のみなさん&lt;/strong&gt;: よい Web サイトの作り方に興味を持ち、このコースを読んでくれた皆さんにも、もちろん感謝しています。&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id="contact"&gt;連絡先&lt;/h2&gt;

&lt;p&gt;より多くの人に対して有益なものとなるよう、私は常にこのコースを見直すようにしています。もしコースへの提案やコメント、どこかで使いたいという要望などあれば、ぜひ連絡してください。Eメールアドレスは cmills [at] opera [dot] com になります。また、全ての記事の下のほうには「この記事についてディスカッションする」というリンクがあり、そこからコメントを投稿することができます。なお、コメントには &lt;a href="http://my.opera.com/community/signup/" title="my.opera.comにサインアップ"&gt;my.opera アカウント&lt;/a&gt;の取得が必要になります。&lt;/p&gt;

&lt;ul class="seriesNav"&gt;
&lt;li class="next"&gt;&lt;a rel="next" href="http://dev.opera.com/articles/view/2-the-history-of-the-internet-and-the-w-ja/"&gt;次の記事: インターネットと Web の歴史、そして Web 標準の進化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel="index" href="http://dev.opera.com/articles/view/1-introduction-to-the-web-standards-cur-ja/#toc"&gt;カリキュラムの目次へ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;著者について&lt;/h2&gt;
&lt;img alt="著者 Chris Mills の写真" src="http://dev.opera.com/articles/view/1-introduction-to-the-web-standards-cur/chrismills.jpg" class="right" /&gt;

&lt;p&gt;Chris Mills は Opera の Developer Relations Manager です。&lt;a href="http://dev.opera.com"&gt;dev.opera.com&lt;/a&gt; や &lt;a href="http://labs.opera.com"&gt;labs.opera.com&lt;/a&gt; で記事を編集・公開する傍ら、コミュニティに Opera の紹介やフィードバックの収集を行い、また Opera のソフトウェアの伝道師としても活躍しています。そして、このWeb標準カリキュラムの編集者兼オーガナイザーでもあります。&lt;/p&gt;

&lt;p&gt;プライベートでは、彼はとても熱心な音楽ファンです。メタルやフォーク、パンク、エレクトロニカ、プログレをはじめさまざまな音楽を聴き、また演奏しています。彼のバンド &lt;a href="http://www.conquestofsteel.co.uk"&gt;Conquest of Steel&lt;/a&gt; もよろしくお願いします。&lt;/p&gt;

&lt;h2&gt;翻訳者について&lt;/h2&gt;

&lt;img alt="翻訳者矢倉眞隆の写真" src="mitsue-myakura.jpg" class="right" /&gt;

&lt;h3&gt;矢倉 眞隆 (Masataka Yakura)&lt;/h3&gt;
&lt;p&gt;1984年生まれ。株式会社ミツエーリンクスにて、社内の品質改善活動や Web 標準 の普及啓蒙を行っている。W3C HTML WG メンバー。&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://www.mitsue.co.jp/"&gt;株式会社 ミツエーリンクス&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;
1990年創業。大規模な Web サイト開発を得意とするインフォメーション・インテ グレータ。自社コンテンツの &lt;a href="http://standards.mitsue.co.jp/"&gt;Web 標準 Blog&lt;/a&gt; や&lt;a href="http://accessibility.mitsue.co.jp/"&gt;アクセシビリティ Blog&lt;/a&gt; より、Web フロントエンド技術に関するさまざまな情報を発信中。&lt;/p&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevOperaFullFeed/~4/4CsdoYOddAw" height="1" width="1"/&gt;</description>
<feedburner:origLink>http://dev.opera.com/articles/view/801</feedburner:origLink></item>
<item rdf:about="http://dev.opera.com/articles/view/855">
<creator>Remigiusz Bondarowicz</creator>
<dc:date>2009-10-15T12:30:53Z</dc:date>
<link>http://feedproxy.google.com/~r/DevOperaFullFeed/~3/AwV4NbxijdM/855</link>
<title>Opera Desktop Widgets evolved</title>
<description>&lt;img src="http://feeds.feedburner.com/~r/DevOperaFullFeed/~4/AwV4NbxijdM" height="1" width="1"/&gt;</description>
<feedburner:origLink>http://dev.opera.com/articles/view/855</feedburner:origLink></item>
<item rdf:about="http://dev.opera.com/articles/view/842">
<creator>Hans S. Tømmerholt</creator>
<dc:date>2009-10-14T06:01:41Z</dc:date>
<link>http://feedproxy.google.com/~r/DevOperaFullFeed/~3/HiDs2-sOtb8/842</link>
<title>Opera Unite developer’s primer — revisited</title>
<description>&lt;div class="article"&gt;&lt;p class="comment"&gt;Content contributions by Arve, Chris, Zi Bin and Lissy.&lt;/p&gt;

&lt;h2&gt;Introduction&lt;/h2&gt;
  
  &lt;p&gt;Opera Unite features a Web server running inside the Opera browser, which allows you to do some amazing things. At the touch of a button, you can share images, documents, video, music, games, collaborative applications and all manner of other things with your friends and colleagues. We released an &lt;a href="http://labs.opera.com/news/2009/06/16/"&gt;Opera Labs build&lt;/a&gt; containing an early version of the Opera Unite server a few months ago, and now we’ve released a &lt;a href="http://www.opera.com/browser/next/"&gt;beta version of Opera 10.10&lt;/a&gt;, featuring a much-improved Opera Unite.&lt;/p&gt;

  &lt;p&gt;This article gets you started on the road to Opera Unite application development — it describes how the Opera Unite server in Opera works and how it can be used. Below I will briefly recap some of the basic concepts related to Opera Unite, show how you can enable the Web server in your browser, and give an example of how to write a simple Opera Unite blog application.&lt;/p&gt;

  &lt;p&gt;The contents of this article are as follows:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;a href="#concepts"&gt;Basic concepts&lt;/a&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;a href="#conceptsunite"&gt;What is Opera Unite?&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#conceptsproxy"&gt;Opera Unite Proxy&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#conceptsapplications"&gt;Opera Unite applications&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href="#enabling"&gt;Enabling your Web server&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#application"&gt;Creating an Opera Unite Application: A simple blog&lt;/a&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;a href="#applicationstructure"&gt;Files and folders in the application&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#applicationconfig"&gt;Configuring the application: config.xml&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#applicationindex"&gt;Tying it together: index.html&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#applicationscript"&gt;Creating the script: script.js&lt;/a&gt;
          &lt;ul&gt;
            &lt;li&gt;&lt;a href="#scriptlisteners"&gt;The request event listeners&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href="#scriptlist"&gt;Showing a list of blog entries&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href="#scriptentry"&gt;Showing a single entry&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href="#scriptfrom"&gt;Showing the form for adding an entry&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href="#scriptsave"&gt;Saving an entry&lt;/a&gt;&lt;/li&gt;
          &lt;/ul&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href="#using"&gt;Using your Opera Unite application&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#viewing"&gt;Viewing your Opera Unite application&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#uploading"&gt;Uploading your Opera Unite application to unite.opera.com&lt;/a&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;a href="#uploadingbefore"&gt;Before publishing&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#uploadingprocess"&gt;Publishing your application&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#uploadinghowto"&gt;How can I get people to try my application?&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#uploadingapproval"&gt;Approval of Opera Unite applications&lt;/a&gt;
          &lt;ul&gt;
            &lt;li&gt;&lt;a href="#uploadingguides"&gt;What are the guidelines for approval of an Opera Unite application?&lt;/a&gt;&lt;/li&gt;
          &lt;/ul&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href="#readmore"&gt;Further reading&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
 

  &lt;h2 id="concepts"&gt;Basic concepts&lt;/h2&gt;

  &lt;p&gt;In this section we’ll run through the basics of how Opera Unite works, and how Opera Unite applications are constructed.&lt;/p&gt;

  &lt;h3 id="conceptsunite"&gt;What is Opera Unite?&lt;/h3&gt;

  &lt;p&gt;Opera Unite is a Web server running inside the Opera Web browser, allowing the user to install applications and share these applications with their friends and colleagues (or everyone, if they wish). The Opera Unite server provides a proxy between the server and its clients (found at &lt;a href="http://www.operaunite.com"&gt;operaunite.com&lt;/a&gt;) to avoid the need for any special firewall configuration.&lt;/p&gt;

  &lt;h3 id="conceptsproxy"&gt;Opera Unite proxy&lt;/h3&gt;

  &lt;p&gt;Traditionally when a user runs a Web server in a home network the
  network has a device that acts as a firewall, which
  needs to be configured separately, as illustrated in Figure 1.&lt;/p&gt;

  &lt;img src="traditio.jpg" alt="traditional web server setup" /&gt;
  &lt;p class="comment"&gt;Figure 1: A traditional Web server setup&lt;/p&gt;

  &lt;p&gt;Typically, the user will need to open ports and enable port forwarding to a local computer in order for people outside the firewall to be able to access the server.&lt;/p&gt;

  &lt;p&gt;However, when the user is using Opera Unite, no configuration is
  needed, as seen in Figure 2.&lt;/p&gt;

  &lt;img src="operauni.jpg" alt="server set up when using the Opera Unite server in your browser" /&gt;
  &lt;p class="comment"&gt;Figure 2: The set up when using the Opera Unite server in your browser&lt;/p&gt;

  &lt;p&gt;The Web server initiates a connection to the proxy, which uses this to pass information back about incoming requests.&lt;/p&gt;

&lt;p class="note"&gt;Note that the proxy is really only a fallback mechanism to ensure that data can be delivered in case &lt;abbr title="Network Address Translation"&gt;NAT&lt;/abbr&gt; traversal fails. Opera Unite has support for &lt;abbr title="Universal Plug and Play"&gt;UPnP&lt;/abbr&gt;, which allows you to share your data using direct connections to your computer, if available. This can make loading speeds for your applications faster as they will bypass the proxy server. However, as it is up to each application to load content using the direct connection, it may not always run applications faster. UPnP has no authentication mechanism, and assumes that local systems and their users are completely trustworthy.&lt;/p&gt;

  &lt;h3 id="conceptsapplications"&gt;Opera Unite applications&lt;/h3&gt;

&lt;p&gt;Opera Unite applications have a &lt;code&gt;config.xml&lt;/code&gt; file containing fundamental information about the application, and a fairly standard web site directory structure. In these respects they are very similar to &lt;a href="http://dev.opera.com/articles/view/creating-your-first-opera-widget/"&gt;Opera Widgets&lt;/a&gt;, although the way Opera Unite applications are run/used is very different to Opera Widgets. They also differ in other ways — unlike in Opera Widgets, Opera Unite &lt;code&gt;config.xml&lt;/code&gt; files must also contain a &lt;code&gt;feature&lt;/code&gt; element like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;feature name="http://xmlns.opera.com/webserver"&amp;gt;
  &amp;lt;param name="type" value="service"/&amp;gt;
  &amp;lt;param name="servicepath" value="blog"/&amp;gt;
&amp;lt;/feature&amp;gt;&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;In this case, a special JavaScript object — &lt;code&gt;opera.io.webserver&lt;/code&gt; — becomes available to the application. See the &lt;a href="http://dev.opera.com/libraries/unite/"&gt;Opera Unite Web Server JavaScript API&lt;/a&gt; for more information.&lt;/p&gt;

  &lt;p&gt;As the Opera Widgets technology is used, the Opera Unite application can provide the person running the Opera Unite server with a simple way of controlling and configuring it, all using standard HTML, CSS and JavaScript. Opera Unite applications do, however, get access to functionality normally not present in widgets or Web pages, for example a 
  &lt;a title="FileI/O JavaScript API" href="http://dev.opera.com/libraries/fileio/"&gt;sandboxed file system&lt;/a&gt;.&lt;/p&gt;
  
&lt;p class="note"&gt;For those of you who are interested in learning more about Opera Widgets, you can &lt;a href="http://dev.opera.com/articles/widgets"&gt;find more Widgets articles on dev.opera&lt;/a&gt;.&lt;/p&gt;

  &lt;p&gt;Let’s move on, get Opera Unite enabled, and start building up a simple Opera Unite application.&lt;/p&gt;

  &lt;h2 id="enabling"&gt;Enabling your Web server&lt;/h2&gt;

  &lt;p&gt;For security and performance reasons, the Web server does not run by default when Opera is started. You enable the server by selecting Tools &amp;gt; Opera Unite Server &amp;gt; Enable Opera Unite, or by opening an Opera Unite application. When you do so, a dialog pops up asking you to specify a username and password. This is your My Opera username and password.&lt;/p&gt;

  &lt;p class="note"&gt;Note that only My Opera usernames containing valid URL characters will work with Opera Unite. Invalid characters include “/”, “.”, “_” and space.&lt;/p&gt;

  &lt;p&gt;In the next wizard screen, you need to define a device. You may select a device name from the drop-down list, or specify your own. The device name is used to identify your server via the proxy. It will be available via a URL like the following:&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;http://&lt;em class="dname"&gt;devicename&lt;/em&gt;.&lt;em class="uname"&gt;username&lt;/em&gt;.&lt;em class="pname"&gt;proxyaddress&lt;/em&gt;/&lt;em class="sname"&gt;applicationname&lt;/em&gt;&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;So, to visit the application &lt;code&gt;test&lt;/code&gt; on the server &lt;code&gt;your_device&lt;/code&gt; on
  &lt;code&gt;operaunite.com&lt;/code&gt;, the URL becomes:&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;http://&lt;em class="dname"&gt;your_device&lt;/em&gt;.&lt;em class="uname"&gt;your_username&lt;/em&gt;.&lt;em class="pname"&gt;operaunite.com&lt;/em&gt;/&lt;em class="sname"&gt;test&lt;/em&gt;&lt;/code&gt;&lt;/pre&gt;

 &lt;h2 id="application"&gt;Creating the Opera Unite application: A simple blog&lt;/h2&gt;

  &lt;p&gt;Here is a short walk-through for creating a simple blogging
  application that allows the user to write blog entries. Once stored,
  the entries are immediately available to the world through the Opera Unite
  server.&lt;/p&gt;

  &lt;p&gt;The application has two parts: One is a configuration view for the application, where the owner can configure and control it. The other part is a series of Web pages generated or served by the application, which are visible to the user.&lt;/p&gt;

  &lt;p&gt;For those who just can’t wait, you can download the &lt;a href="blog.ua"&gt;Opera Unite blog source code&lt;/a&gt; and start playing with it already. It is packaged with a &lt;code&gt;.ua&lt;/code&gt; extension, the default extension for Opera Unite applications. You can unzip the package to look at the source code or drag the package into the Opera browser to fire up the Opera Unite blog example.&lt;/p&gt;

  &lt;h3 id="applicationstructure"&gt;Files and folders in the application&lt;/h3&gt;

  &lt;p&gt;The blog application will contain the files and folders shown in Figure 3:&lt;/p&gt;

&lt;img src="structur.jpg" alt="The directory structure of the application" /&gt;
  &lt;p class="comment"&gt;Figure 3: The directory structure of the application&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;code&gt;config.xml&lt;/code&gt;: Configuration file for the application.&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;index.html&lt;/code&gt;: Starting logic for the application, including scripts.&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;script/script.js&lt;/code&gt;: The actual Web server code.&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;Of these, only &lt;code&gt;config.xml&lt;/code&gt; and &lt;code&gt;index.html&lt;/code&gt; are required.&lt;/p&gt;

  &lt;p&gt;You may include a &lt;code&gt;public_html&lt;/code&gt; folder, which is a magic 
  folder in Opera Unite applications. Normally, files and folders inside your application are not available to users requesting your application, so if you want to distribute a separate stylesheet, static images and similar, those files go inside here. These files are mapped to the relative root of your application, so a file named &lt;var&gt;cats.png&lt;/var&gt; inside the &lt;code&gt;public_html&lt;/code&gt; folder of the &lt;em&gt;helloOperaUnite&lt;/em&gt; application will be available at&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;&lt;a href="http://your_device.your_username.operaunite.com/helloOperaUnite/cats.png" target="_blank"&gt;http://your_device.your_username.operaunite.com/helloOperaUnite/cats.png&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;

  &lt;h3 id="applicationconfig"&gt;Configuring the application: config.xml&lt;/h3&gt;

  &lt;p&gt;This application will be packaged in the same way as an Opera Widget, so we’ll need to define a &lt;code&gt;config.xml&lt;/code&gt; file. The file is just like a normal Opera Widgets’ &lt;code&gt;config.xml&lt;/code&gt; file, with a few extra details. In order to identify your application as an Opera Unite application, you need to add a &lt;code&gt;feature&lt;/code&gt; element to the &lt;code&gt;widget&lt;/code&gt; element in your &lt;code&gt;config.xml&lt;/code&gt; file.&lt;/p&gt;

  &lt;p class="note"&gt;Please note that Opera Widgets are packaged as regular zip files and renamed to use the extension &lt;code&gt;.wgt&lt;/code&gt;, whereas Opera Unite applications are packaged and renamed to use the extension &lt;code&gt;.ua&lt;/code&gt; to denote “Unite Application”.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;widget&amp;gt;
  &amp;lt;widgetname&amp;gt;My blogging application&amp;lt;/widgetname&amp;gt;
  &amp;lt;description&amp;gt;Blogging application example from the Opera Unite applications primer.&amp;lt;/description&amp;gt;
  &amp;lt;author&amp;gt;
    &amp;lt;name&amp;gt;Hans S. Toemmerholt&amp;lt;/name&amp;gt;
    &amp;lt;organisation&amp;gt;Opera Software ASA&amp;lt;/organisation&amp;gt;
  &amp;lt;/author&amp;gt;
  &amp;lt;feature name="http://xmlns.opera.com/webserver"&amp;gt;
    &amp;lt;param name="type" value="service"/&amp;gt;
    &amp;lt;param name="servicepath" value="blog"/&amp;gt;
  &amp;lt;/feature&amp;gt;
&amp;lt;/widget&amp;gt;&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;The &lt;code&gt;widgetname&lt;/code&gt; element of the application also acts as its application name. This is the name which will be shown to the user when installing and using the application.&lt;/p&gt;

  &lt;p&gt;You may also add a &lt;code&gt;servicepath&lt;/code&gt; element to the &lt;code&gt;config.xml&lt;/code&gt; file.
  The content of this element must be a valid part of a URI and defines what the &lt;em&gt;name of your application will be in the URI&lt;/em&gt; of the application.
  If this element is not present, Opera will attempt to use the content of the 
  &lt;code&gt;widgetname&lt;/code&gt; element as the URI component. If this name is not valid as a URI component, the installation of the application will fail with an error message.&lt;/p&gt;

  &lt;p&gt;When the application is packaged and run, the above &lt;code&gt;config.xml&lt;/code&gt; will make it respond to&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;http://&lt;em class="dname"&gt;your_device&lt;/em&gt;.&lt;em class="uname"&gt;your_username&lt;/em&gt;.&lt;em class="pname"&gt;operaunite.com&lt;/em&gt;/&lt;em class="sname"&gt;blog/&lt;/em&gt;&lt;/code&gt;&lt;/pre&gt;

  &lt;h3 id="applicationindex"&gt;Tying it together: index.html&lt;/h3&gt;

  &lt;p&gt;An application has no UI beyond the Web pages it produces. &lt;code&gt;index.html&lt;/code&gt; is the starting point for the application, so that &lt;em&gt;is&lt;/em&gt; the UI. In our example, we’ll use a minimal HTML 5 file with a reference to the script we’re using:&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;script src="script/script.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;

  &lt;h3 id="applicationscript"&gt;Creating the script: script.js&lt;/h3&gt;

  &lt;p&gt;Note the link to the script file &lt;var&gt;script.js&lt;/var&gt; in the
  above code snippet. The Web server listens to requests made from
  clients (users browsing the URL of the application) and creates
  responses that are sent back. The response is typically a
  generated Web page containing information.&lt;/p&gt;

  &lt;p&gt;The functionality in Opera Unite is exposed to developers through a set of &lt;a title="Opera Unite Web Server JavaScript API" href="http://dev.opera.com/libraries/unite/"&gt;JavaScript APIs&lt;/a&gt;, including objects representing the Web server, connections, incoming requests and outgoing responses.&lt;/p&gt;

  &lt;p&gt;What follows is a walk-through of the script.&lt;/p&gt;

  &lt;h4 id="scriptlisteners"&gt;The request event listeners&lt;/h4&gt;

  &lt;p&gt;A Web server handles requests from clients and sends responses back
  to them. The Opera Unite Web server is &lt;em&gt;event-based&lt;/em&gt; and will raise a DOM event in the application every time a Web browser makes a connection to the server asking for files related to the Opera Unite application. In order to respond to such events, we need to set up event listeners. This is done in &lt;code&gt;window.onload&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var webserver;
var entries = [];

window.onload = function () {

    webserver = opera.io.webserver

    if (webserver)
    {
        //Handle requests for various URLs
        webserver.addEventListener('_index', showEntryList, false);
        webserver.addEventListener('entry', showEntry, false);
        webserver.addEventListener('form', showForm, false);
        webserver.addEventListener('save', saveEntry, false);
    }
}
&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;What is going on here?&lt;/p&gt;

  &lt;p&gt;We are checking if the application is actually a web application, by
  checking for the &lt;code&gt;webserver&lt;/code&gt; object. If it is present, we add four event listeners — &lt;code&gt;_index&lt;/code&gt;,
  &lt;code&gt;entry&lt;/code&gt;, &lt;code&gt;form&lt;/code&gt; and &lt;code&gt;save&lt;/code&gt;.&lt;/p&gt;

  &lt;p&gt;When these listeners are set up, the application will now call one of
  the functions each time a user visits one of the following URLs:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;code&gt;&lt;a href="http://your_device.your_username.operaunite.com/blog/" target="_blank"&gt;http://your_device.your_username.operaunite.com/blog/&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;&lt;a href="http://your_device.your_username.operaunite.com/blog/" target="_blank"&gt;http://your_device.your_username.operaunite.com/blog/&lt;/a&gt;&lt;em class="ename"&gt;entry&lt;/em&gt;&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;&lt;a href="http://your_device.your_username.operaunite.com/blog/" target="_blank"&gt;http://your_device.your_username.operaunite.com/blog/&lt;/a&gt;&lt;em class="ename"&gt;form&lt;/em&gt;&lt;/code&gt;&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;The &lt;code&gt;_index&lt;/code&gt; request is special, and means a request to the root path of the application. Also note that, as we shall see, the user will not visit “save” directly — only through the form.&lt;/p&gt;

  &lt;h4 id="scriptlist"&gt;Showing a list of blog entries&lt;/h4&gt;

  &lt;p&gt;The code for the &lt;code&gt;_index&lt;/code&gt; request, the &lt;code&gt;showEntryList&lt;/code&gt; function, is quite simple. When receiving a request, it writes back a HTML page with a list of the saved entries.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function showEntryList(e)
{
    var response = e.connection.response;
    response.write( '&amp;lt;!DOCTYPE html&amp;gt;'
        + '&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Entries&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;'
        + '&amp;lt;body&amp;gt;&amp;lt;ul&amp;gt;'
    );

    for ( var i = 0, entry; entry = entries&lt;i&gt;; i++ )
    {
        response.write('&amp;lt;li&amp;gt;'+entry.date+': &amp;lt;a href="entry?id='+i+'"&amp;gt;'+entry.title+'&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;');
    }

    response.write('&amp;lt;/ul&amp;gt;'
      + '&amp;lt;p&amp;gt;&amp;lt;a href="form"&amp;gt;Add en entry&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;'
      + '&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;'
    );
    response.close();
}&lt;/i&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Line-by-line, the script does the following:&lt;/p&gt;

&lt;p&gt;It first gets a reference to the &lt;code&gt;response&lt;/code&gt; object. This is the object that holds the methods necessary to send output back to the client:&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;var response = e.connection.response;&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;The &lt;code&gt;write&lt;/code&gt; method then writes the content to the web
  browser that requested the page. First, we write a simple HTML shell:&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;response.write( '&amp;lt;!DOCTYPE html&amp;gt;'
    + '&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Entries&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;'
    + '&amp;lt;body&amp;gt;&amp;lt;ul&amp;gt;'
);&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;The existing blog entries are marked up as a list with links to
  the individual entries:&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;for ( var i = 0, entry; entry = entries&lt;i&gt;; i++ )
{
    response.write('&amp;lt;li&amp;gt;'+entry.date+': &amp;lt;a href="entry?id='+i+'"&amp;gt;'+entry.title+'&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;');
}&lt;/i&gt;&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;Finally, we close the connection.&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;response.close();&lt;/code&gt;&lt;/pre&gt;

  &lt;h4 id="scriptentry"&gt;Showing a single entry&lt;/h4&gt;

  &lt;p&gt;Next, we need to output something when the user clicks a 
  link to an entry:&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;function showEntry(e)
{
    var index = e.connection.request.queryItems['id'][0];
    var entry = entries[index];
    //ToDo Should have error handling here
    var response = e.connection.response;
    response.write('&amp;lt;!DOCTYPE html&amp;gt;'
        + '&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;'+entry.title+'&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;'
        + '&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;'+entry.title+'&amp;lt;/h1&amp;gt;'
        + '&amp;lt;p&amp;gt;'+entry.date+'&amp;lt;/p&amp;gt;'
        + '&amp;lt;div&amp;gt;'+entry.text+'&amp;lt;/div&amp;gt;'
        + '&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;'
    );
    response.close();
}&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;Line-by-line, the script does the following:&lt;/p&gt;

  &lt;p&gt;It first gets a reference to the &lt;code&gt;request&lt;/code&gt; object, which
  contains information about the incoming request:&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;var request = e.connection.request;&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;CGI GET arguments are stored in the &lt;code&gt;queryItems&lt;/code&gt; 
  property of the request. We get the &lt;code&gt;id&lt;/code&gt; of the entry to display. 
  Note that the the same CGI argument may have multiple values: &lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;var index = request.queryItems['id'][0];&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;Next we get the corresponding blog entry:&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;var entry = entries[index];&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;The &lt;code&gt;write&lt;/code&gt; method then writes the content to the web
  browser that requested the page. The title, date and text of the blog entry
  are wrapped in suitable markup:&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;response.write('&amp;lt;!DOCTYPE html&amp;gt;'
    + '&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;'+entry.title+'&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;'
    + '&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;'+entry.title+'&amp;lt;/h1&amp;gt;'
    + '&amp;lt;p&amp;gt;'+entry.date+'&amp;lt;/p&amp;gt;'
    + '&amp;lt;div&amp;gt;'+entry.text+'&amp;lt;/div&amp;gt;'
    + '&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;'
);&lt;/code&gt;&lt;/pre&gt;


  &lt;h4 id="scriptfrom"&gt;Showing the form for adding an entry&lt;/h4&gt;

  &lt;p&gt;When you click the “Add an entry” link, a classic Web form is displayed:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function showForm(e)
{
    var response = e.connection.response;
    response.write('&amp;lt;!DOCTYPE html&amp;gt;'
        + '&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Add entry&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;'
        + '&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;Add entry&amp;lt;/h1&amp;gt;'
        + '&amp;lt;form method="post" action="save"&amp;gt;'
        + '&amp;lt;p&amp;gt;&amp;lt;label for="namefield"&amp;gt;Title&amp;lt;/label&amp;gt; &amp;lt;input id="nameField" type="text" name="title"&amp;gt;&amp;lt;/p&amp;gt;'
        + '&amp;lt;p&amp;gt;&amp;lt;label for="textArea"&amp;gt;Text&amp;lt;/label&amp;gt; &amp;lt;textarea id="textArea" name="text"&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;/p&amp;gt;'
        + '&amp;lt;p&amp;gt;&amp;lt;input type="submit" name="Add entry"&amp;gt;&amp;lt;/p&amp;gt;'
        + '&amp;lt;/form&amp;gt;'
        + '&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;'
    );
    response.close();
}&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;This could be a lot more complicated, eg handling error messages, adding pre-populated values, input validation and so on. Ideally you should also offer some authentication scheme to guard against potentially destructive data operations, but we’ve kept it simple to highlight the Opera Unite knowledge.&lt;/p&gt;

  &lt;h4 id="scriptsave"&gt;Saving an entry&lt;/h4&gt;

  &lt;p&gt;Finally, when you submit the form, a new entry should be saved. For now, entries are stored in a simple array so will be lost when the application is restarted, but it wouldn’t be so hard to extend the example to provide a means of retaining the blog entries.&lt;/p&gt;

  &lt;pre&gt;function saveEntry(e)
{
    var request = e.connection.request
    var response = e.connection.response;

    //Get POST data
    var title = request.bodyItems['title'][0];
    var text = request.bodyItems['text'][0];

    entries.push({
        'title' : title, 
        'text'  : text,
        'date'  : new Date()
    });


    //Redirect back to the index of the application
    response.setStatusCode(302);
    response.setResponseHeader( 'Location', webserver.currentServicePath );
    response.close();
}&lt;/pre&gt;

  &lt;p&gt;Instead of &lt;code&gt;request.queryItems&lt;/code&gt;, we use the &lt;code&gt;bodyItems&lt;/code&gt; property to access data sent by POST, in this case the title and the content of the new entry.&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;var title = request.bodyItems['title'][0];
var text = request.bodyItems['text'][0];&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Submitting the form saves the entry, storing it in an array:&lt;/p&gt;
  
    &lt;pre&gt;&lt;code&gt;entries.push({
      'title' : title,
      'text'  : text,
      'date'  : new Date()
  });&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;Finally, when the entry is saved, we redirect back to the list of 
  entries:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;response.setStatusCode(302);
response.setResponseHeader( 'Location', webserver.currentServicePath );
response.close();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here we create a standard HTTP temporary redirect back to the root of the application, represented by the &lt;code&gt;webserver.currentServicePath&lt;/code&gt; property. This will fire an &lt;code&gt;_index&lt;/code&gt; request, and the list of entries will then be shown.&lt;/p&gt;

  &lt;p&gt;Again, in a production-level you should add error handling and status messages to this.&lt;/p&gt;

  &lt;h2 id="using"&gt;Using your Opera Unite application&lt;/h2&gt;

  &lt;p&gt;In order to get your Opera Unite application running, you simply need to load the application. Click and drag its &lt;code&gt;config.xml&lt;/code&gt; file or a zipped version of the whole application into your browser window. Alternatively, open &lt;code&gt;config.xml&lt;/code&gt; from a file
  dialog. If you have not previously started any Opera Unite applications, the Opera Unite configuration dialog will now appear.&lt;/p&gt;

&lt;p&gt;Double click &lt;em&gt;My blogging application&lt;/em&gt; in the Opera Unite applications pane and you should get a page appearing in the browser window, as seen in Figure 4:&lt;/p&gt;
  
   &lt;img src="blogmain.jpg" alt="The blog application main screen" /&gt;
   &lt;p class="comment"&gt;Figure 4: The blog application main screen.&lt;/p&gt;

  &lt;p&gt;Clicking the &lt;em&gt;Add an entry&lt;/em&gt; link will take you to a form that allows you to add a blog entry, as seen in Figure 5.&lt;/p&gt;

&lt;img src="blogform.jpg" alt="A form for entering a new blog entry" /&gt;
   &lt;p class="comment"&gt;Figure 5: The form for entering a new blog post.&lt;/p&gt;


&lt;p&gt;When you enter some text and press submit, you are taken back to the blog main screen and your blog entry is available to view. You can click on the blog entry title to view the post. Add a few blog entries, have a play around, and you should end up with something like Figure 6.&lt;/p&gt;

&lt;img src="fullblog1.jpg" alt="A few blog entries entered into the blog application" /&gt;
&lt;img src="fullblog2.jpg" alt="An expanded full blog entry" /&gt;
   &lt;p class="comment"&gt;Figure 6: Our blog is now nicely populated.&lt;/p&gt;

  &lt;h2 id="viewing"&gt;Viewing your Opera Unite application&lt;/h2&gt;

  &lt;p&gt;If you followed this guide and started the application in Opera, you 
  should now have a functioning web application. Anyone can visit it
  by going to the URL&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;http://&lt;em class="dname"&gt;devicename&lt;/em&gt;.&lt;em class="uname"&gt;username&lt;/em&gt;.&lt;em class="pname"&gt;proxyaddress&lt;/em&gt;/&lt;em class="sname"&gt;applicationname&lt;/em&gt;&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;In this case, if the device is called &lt;em class="dname"&gt;your_device&lt;/em&gt; 
  and it’s running the blog application, the URL becomes:&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;http://&lt;em class="dname"&gt;your_device&lt;/em&gt;.&lt;em class="uname"&gt;username&lt;/em&gt;.&lt;em class="pname"&gt;operaunite.com&lt;/em&gt;/&lt;em class="sname"&gt;blog&lt;/em&gt;&lt;/code&gt;&lt;/pre&gt;

   &lt;p&gt;As you saw when running the example above, you can visit the root
  address of the device to see the installed applications on a system, for example:&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;http://&lt;em class="dname"&gt;your_device&lt;/em&gt;.&lt;em class="uname"&gt;username&lt;/em&gt;.&lt;em class="pname"&gt;operaunite.com&lt;/em&gt;/&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;This page will contain information on which applications are installed
  on the system, and if the information is found in &lt;code&gt;config.xml&lt;/code&gt;, it will
  also list information on each application, including author, description, etc.&lt;/p&gt;

  &lt;h2 id="uploading"&gt;Uploading your Opera Unite application onto unite.opera.com&lt;/h2&gt;

&lt;p&gt;So now you’ve put together a cool Opera Unite application you not only want to let people use it via your Opera Unite server, you also want to make it available for others to download and install on their Opera Unite servers, right? So how do we do this? The answer is to upload them to &lt;a href="http://unite.opera.com"&gt;unite.opera.com&lt;/a&gt; — this is the site where Opera Unite applications are distributed. This section will show you how.&lt;/p&gt;

&lt;h3 id="uploadingbefore"&gt;Before publishing&lt;/h3&gt;

&lt;p&gt;Before publishing you should test your application to find bugs. Test on different platforms, devices and Opera browser versions if you can. Also remember that people using your applications can do so from any browser, not just Opera, so test your application’s pages in other browsers (Firefox, Safari, etc.).&lt;/p&gt;

&lt;p&gt;If you are having trouble getting your application to work and you are convinced that the actual code of the application is right, check your &lt;code&gt;config.xml&lt;/code&gt; file for errors. It needs to work for the application to be accepted. Opening the file in a different browser will check it for well-formedness. Check also that your &lt;code&gt;config.xml&lt;/code&gt; file contains enough information. We will use this file to supply information about your application to &lt;a href="http://unite.opera.com"&gt;unite.opera.com&lt;/a&gt; and to the Opera Unite application page on computers where the application is installed.&lt;/p&gt;

&lt;p&gt;Also consider translating the application, if this is appropriate and you can do so.&lt;/p&gt;

&lt;p&gt;Finally, take a screenshot of the application in action, as described below.&lt;/p&gt;


&lt;h3 id="uploadingprocess"&gt;Publishing your application&lt;/h3&gt;

&lt;p&gt;To do this, you need to visit Opera’s &lt;a href="http://unite.opera.com/applications/upload/"&gt;Upload page&lt;/a&gt;. Select your application archive file in the archive file chooser dialog and upload it. Read through and verify the information taken from your &lt;code&gt;config.xml&lt;/code&gt; file. Feel free to add more text if you wish.&lt;/p&gt;

&lt;p&gt;Next up, select your screenshot in the screenshot file dialog box so that others will be able to see what your application looks like before they try it out.&lt;/p&gt;

&lt;p&gt;You also need to select the target devices that your application is designed to be used with. Make sure you have tested it on those devices. Select a relevant group for your application. The last step is to select the target languages for your application. Make sure you have supplied translations for all the languages you select.&lt;/p&gt;

&lt;h3 id="uploadinghowto"&gt;How can I get people to try my application?&lt;/h3&gt;

&lt;p&gt;When you have spent a lot of time making an application, you’ll naturally want people to try it out. To increase the number of views, use the application descriptions to tell potential users what to expect when running the application. Each application has a short description, automatically copied from your &lt;code&gt;config.xml&lt;/code&gt; file, and a long description where you can provide more details and tips for use.&lt;/p&gt;

&lt;p&gt;Use the short description to catch the user’s eye, stating what your application does and what value users can get out of it. It may be a tagline, but it should be informative. You should avoid phrases like “Download me” or “This is a super cool app” which are likely to turn users away. Use the long description to tell people what features your application has, how it was implemented, about changes in different versions, rules for games, and so on.&lt;/p&gt;

&lt;p&gt;Finally, don’t forget to take a screenshot of your application in action. For inspiration, the &lt;a href="http://unite.opera.com/applications/author/OperaUnite/"&gt;Opera Unite team’s applications&lt;/a&gt; are a good place to start.&lt;/p&gt;

&lt;p class="note"&gt;Note that you should ideally make your screenshots 445 x 230 pixels — this is the size we have been using on the &lt;a href="http://unite.opera.com"&gt;Opera Unite web site&lt;/a&gt;. If you use different-sized screenshots they will be resized, which may lead to undesirable results.&lt;/p&gt;

&lt;h3 id="uploadingapproval"&gt;Approval of Opera Unite applications&lt;/h3&gt;

&lt;p&gt;All applications need to be approved by Opera Software staff. We check for errors to ensure that our users have a good online experience, but we do not take responsibility for the content of the applications or make any guarantees about the functionality. See our &lt;a href="http://unite.opera.com/disclaimer/"&gt;disclaimer&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id="uploadingguides"&gt;What are the guidelines for approval of an Opera Unite application?&lt;/h4&gt;

&lt;p&gt;These are some of the guidelines that apply to applications:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The application must have a sensible name and description.&lt;/li&gt;
  &lt;li&gt;The application must not have obvious bugs, so ensure that you test it before uploading.&lt;/li&gt;
  &lt;li&gt;The application must not contain malicious or destructive code.&lt;/li&gt;
  &lt;li&gt;The application must not contain or use copyrighted information for which you do not hold the rights.&lt;/li&gt;
  &lt;li&gt;The application must not contain or point to adult or hateful content.&lt;/li&gt;
  &lt;li&gt;The application should serve standards-compliant HTML pages that are viewable in all modern browsers on a variety of devices.&lt;/li&gt;
&lt;/ul&gt;   


  &lt;h2 id="readmore"&gt;Further reading&lt;/h2&gt;

  &lt;p&gt;Now that you are familiar with the basics of creating and uploading Opera Unite applications, you might want to delve a bit deeper:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;a href="http://dev.opera.com/libraries/unite/"&gt;The Opera Unite JavaScript API&lt;/a&gt; — JSDoc-style reference for the JavaScript interfaces and methods available for the Opera Unite Web Server.&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://dev.opera.com/libraries/fileio/"&gt;The Opera File I/O JavaScript API&lt;/a&gt; — JSDoc-style reference for the JavaScript
    interfaces and methods available for working with files and directories.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/markuper-unite-template-library/"&gt;Markuper: The Opera Unite application template library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.opera.com/articles/view/yusef-the-unite-service-framework/"&gt;Yusef: The Opera Unite Service Framework&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevOperaFullFeed/~4/HiDs2-sOtb8" height="1" width="1"/&gt;</description>
<feedburner:origLink>http://dev.opera.com/articles/view/842</feedburner:origLink></item>
<item rdf:about="http://dev.opera.com/articles/view/790">
<creator>Zi Bin, Cheah</creator>
<dc:date>2009-10-14T06:00:59Z</dc:date>
<link>http://feedproxy.google.com/~r/DevOperaFullFeed/~3/ZKNYIcqNoKY/790</link>
<title>Yusef: the Unite Server Framework</title>
<description>&lt;div class="article"&gt;&lt;p class="comment"&gt;Content contributions by Mathieu Henri, Hans S. Tømmerholt and Gautam Chandna.&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;
This article gets you started with Opera Unite’s Server Framework: Yusef. After reading this article, you will be able to start harnessing the strength of Yusef. Included is a simple example to get things going. 
&lt;/p&gt;
&lt;p&gt;
If you have not read the &lt;a href="http://dev.opera.com/articles/view/opera-unite-developer-primer-revisited/"&gt;Opera Unite developer primer&lt;/a&gt;, we encourage you to do so before starting with Yusef.
&lt;/p&gt;
&lt;p&gt;
The article structure is as follows:
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="#Basic_Concepts"&gt;Basic Concepts&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#Yusef_Core"&gt;Yusef Core&lt;/a&gt;&lt;/li&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href="#Section"&gt;Section&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href="#Action"&gt;Action&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href="#Plugin"&gt;Plugin&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;li&gt;&lt;a href="#Example"&gt;Example&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#Summary"&gt;Summary&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#Reference"&gt;Reference Materials&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="Basic_Concepts"&gt;Basic Concepts&lt;/h2&gt;
&lt;p&gt;
The Unite Server Framework — or Yusef — was started as a way to manage different functional requirements of Opera Unite applications. It was initially created by Opera’s Web Apps team to ease the development of Opera Unite applications. It soon evolved into a large framework covering multiple aspects of making an application.
&lt;/p&gt;
&lt;p&gt;
For a developer, Yusef helps you take care of things such as providing a UI template, form POST validation and access control (amongst others). It evolved out of a need to modularize work in Opera Unite and is here to ease your work.&lt;/p&gt;

&lt;img src="http://devfiles.myopera.com/articles/790/yusef_model_4.png" alt="Diagram of Yusef and an Opera Unite application page" /&gt;
&lt;p class="comment"&gt;Figure 1: Yusef and an Opera Unite application page.&lt;/p&gt;

&lt;p class="note"&gt;
Think of Yusef as a daemon service that runs in the background, and your script as server-side JavaScript. After all that is processed, an HTML page is dumped, which is the Opera Unite application.
&lt;/p&gt;
&lt;h2 id="Yusef_Core"&gt;Yusef Core&lt;/h2&gt;
&lt;p&gt;
Yusef Core provides the backbone of an  Opera Unite application and deals with mount points, the sharing of static files, section listeners (the root or subpaths of the application), form actions (validated by means of a cryptographic nonce — a secure one-time random number used for authentication) and features some hooks to extend these basic functions and add plugins. 
&lt;/p&gt;
&lt;p&gt;
There are three main parts in the Yusef Core. &lt;i&gt;Section&lt;/i&gt; and &lt;i&gt;Actions&lt;/i&gt; are ways Yusef listens to events triggered by users in an Opera Unite application page, while &lt;i&gt;Plugins&lt;/i&gt; introduce extra features such as access control.&lt;/p&gt;

&lt;img src="http://devfiles.myopera.com/articles/790/3part.png" alt="Section, Action, Plugin" /&gt;
&lt;p class="comment"&gt;Figure 2: The three fundamentals of the Yusef Core.&lt;/p&gt;

&lt;h3 id="Section"&gt;Section&lt;/h3&gt;
&lt;p&gt;
Sections are the topmost subpath in which a request is made (ie &lt;code&gt;&lt;a href="http://device.user.opeaunite.com/application/section" target="_blank"&gt;http://device.user.opeaunite.com/application/section&lt;/a&gt;&lt;/code&gt;). Developers can add a section listener method to respond to requests made into a given top most subpath, or at the top &lt;code&gt;_index&lt;/code&gt; level of the service. For example, a section listener might listen to the URL subpath and fire an event called &lt;code&gt;showFileList&lt;/code&gt; when users view the page with a subpath &lt;code&gt;showFileList&lt;/code&gt; — &lt;a href="http://device.user.operaunite.com/application/showFileList." target="_blank"&gt;http://device.user.operaunite.com/application/showFileList.&lt;/a&gt; The event can then perform an action, such as showing a list of files.
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;addSectionListener&lt;/code&gt; is a Yusef method that listens to HTTP requests and registers them to a function. It allows Yusef to listen and perform actions when a page is loaded. The event is tied to a path (section), for example &lt;code&gt;&lt;a href="http://device.user.operaunite.com/application/sectionevent1/" target="_blank"&gt;http://device.user.operaunite.com/application/sectionevent1/&lt;/a&gt;&lt;/code&gt; can be tied to &lt;code&gt;addSectionListener('sectionevent1', function(),args);&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Yusef Core itself creates a section called &lt;code&gt;static&lt;/code&gt; which serves all content located in the application’s &lt;code&gt;public_html&lt;/code&gt; folder. This is used to serve static resources such as the icon, style sheets, scripts and graphics of the application.
&lt;/p&gt;
&lt;h3 id="Action"&gt;Action&lt;/h3&gt;
&lt;p&gt;
Unite actions are the way Yusef deals with a form POST. Developers can register an action listener to process the data posted by a form. The function &lt;code&gt;registerUniteActionListener&lt;/code&gt; listens to POST requests and registers each of them to a specific function. Each POST request corresponds to a unique function. 
&lt;p&gt;
For example, a form may submit data to the root of the application - &lt;code&gt;&lt;a href="http://device.user.operaunite.com/application/" target="_blank"&gt;http://device.user.operaunite.com/application/&lt;/a&gt;&lt;/code&gt;
&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;
 &amp;lt;input type="hidden" name="unite-action" value="&amp;lt;action name&amp;gt;"&amp;gt;
 &amp;lt;input type="hidden" name="unite-nonce" value="&amp;lt;session.nonce&amp;gt;"&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
The form POST must include these two arguments which is needed by Yusef to validate and forward the entire request to your assigned &lt;code&gt;actionListener&lt;/code&gt;. The cryptographic nonce is used for authentication.
&lt;/p&gt;
&lt;h3 id="Plugin"&gt;Plugin&lt;/h3&gt;
&lt;p&gt;
Yusef provides several plugins, amongst them are &lt;abbr title="Access Control List"&gt;ACL&lt;/abbr&gt; and UI plugins. Developers who want to extend Yusef functionality can either create a new plugin or extend the public method of Yusef plugins.
&lt;/p&gt;
&lt;p&gt;We will be looking more closely at plugins in future articles.&lt;/p&gt;
&lt;h2 id="Example"&gt;Example&lt;/h2&gt;
&lt;p&gt;
Before we dive into the code, let’s revisit a few ideas. Yusef is a server-side framework. Code written will be processed on the backend. The entry point of an Opera Unite application is a special index.html page, used to invoke Yusef and other server side functions and libraries. This index.html is not used to display a page but just to invoke scripts. You can think of the whole process as a daemon.
&lt;/p&gt;
&lt;p&gt;
In this example, we want to start an Opera Unite application with Yusef as the framework. Download a &lt;a href="http://devfiles.myopera.com/articles/790/helloYusef.ua"&gt;Yusef Core example&lt;/a&gt;. The basic file structure is
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;index.html&lt;/li&gt;
&lt;li&gt;config.xml&lt;/li&gt;
&lt;li&gt;libraries/yusef&lt;/li&gt;
&lt;li&gt;libraries/Markuper&lt;/li&gt;
&lt;li&gt;libraries/PSO&lt;/li&gt;
&lt;li&gt;serverScripts/helloYusef.js&lt;/li&gt;
&lt;li&gt;templates/helloYusef.html&lt;/li&gt;
&lt;li&gt;public_html/style.css&lt;/li&gt;

&lt;/ul&gt;
&lt;h3&gt;config.xml&lt;/h3&gt;
&lt;p&gt;
config.xml is the descriptor of an Opera Unite application. It is where we tell users the application name and what this application is about.  Opera Unite's config.xml structure is identical to the Opera Widgets config.xml specification.
&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;widget network="public" version="1.0" id="Unite/helloYusef/" &amp;gt;
&amp;lt;widgetname&amp;gt;Hello Yusef&amp;lt;/widgetname&amp;gt;
&amp;lt;description&amp;gt;An example application that uses Yusef, access control and Markuper.&amp;lt;/description&amp;gt;
        &amp;lt;feature name="http://xmlns.opera.com/webserver"&amp;gt;
        &lt;param name="type" value="service" /&gt;
        &lt;param name="servicepath" value="hello_yusef" /&gt;
        &amp;lt;/feature&amp;gt;
        &amp;lt;feature name="http://xmlns.opera.com/fileio"&amp;gt;
        &amp;lt;/feature&amp;gt;
&amp;lt;icon width='64' height='64' &amp;gt;public_html/favicon.64x64.png&amp;lt;/icon&amp;gt;
        &amp;lt;icon width='48' height='48' &amp;gt;public_html/favicon.48x48.png&amp;lt;/icon&amp;gt;
        &amp;lt;icon width='32' height='32' &amp;gt;public_html/favicon.32x32.png&amp;lt;/icon&amp;gt;
&amp;lt;icon width='16' height='16' &amp;gt;public_html/favicon.16x16.png&amp;lt;/icon&amp;gt;
&amp;lt;author&amp;gt;
&amp;lt;name&amp;gt;Gautam Chandna, Opera Software ASA&amp;lt;/name&amp;gt;
&amp;lt;/author&amp;gt;
&amp;lt;/widget&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
We are calling our application "Hello Yusef". It is mandatory to specify the Web server and File I/O needed in our Opera Unite application.
&lt;/p&gt;
&lt;p class="note"&gt;
Including File I/O in the application descriptor might be counter intuitive for applications that don’t need File I/O. However, File I/O is required for access to a sandbox for application data.
&lt;/p&gt;
&lt;h3&gt;index.html&lt;/h3&gt;
&lt;p&gt;
The entry point of an Opera Unite application is index.html. Remember that this index.html is used to invoke libraries and Yusef, not to display content.
&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
&amp;lt;script src="libraries/PSO/pso.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src="libraries/Markuper/template.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src="libraries/yusef/common.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src="libraries/yusef/core.js"&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
Core.js and common.js are both Yusef files. We are using &lt;a href="http://dev.opera.com/articles/view/markuper-unite-template-library/"&gt;Markuper&lt;/a&gt; as our UI template.
&lt;/p&gt;
&lt;h3&gt;ServerScripts/HelloYusef.js&lt;/h3&gt;
&lt;p&gt;
Opera Unite applications that use Yusef as the framework have a magic folder called &lt;code&gt;serverScripts&lt;/code&gt;. Scripts in this folder are automatically invoked and all scripts related to the server side of your application can be placed in this folder.
&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
    Yusef.addSectionListener
    (
        '_index',
        function( connection )
        {
          ...
        }
    );
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
Inside HelloYusef.js, Yusef functions are invoked. Member functions of Yusef are invoked through a Yusef singleton — a class/object that is instantiated once, hence &lt;code&gt;Yusef&lt;/code&gt; is always the object name. For example &lt;code&gt;addSectionListener&lt;/code&gt; function is invoked via &lt;code&gt;Yusef.addSectionListener&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
The &lt;code&gt;addSectionListener&lt;/code&gt; listens to subpaths in a URI. For example, when accessing &lt;code&gt;device.user.operaunite.com/addfile&lt;/code&gt;, the listener for &lt;code&gt;addfile&lt;/code&gt; is fired.
Here we have a listener listening to &lt;code&gt;_index&lt;/code&gt; — which is fired when the top level URI of an Opera Unite application is accessed. 
&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
 function( connection )
        {
   var tmpl = new Markuper( 'templates/helloYusef.html' );
            var data = {
                title       : connection.request.path,
                servicePath : opera.io.webserver.currentServicePath,
                content     : "Hello Yusef",
                stylesheet  : 'style.css'
            }
            tmpl.parse( data );
            return tmpl.html();
}
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
Let’s look at the function that is invoked. The &lt;a href="http://dev.opera.com/articles/view/markuper-unite-template-library/"&gt;Markuper template library&lt;/a&gt; is called with the location of the template as an argument. An object notation variable &lt;i&gt;data&lt;/i&gt; is instantiated with values. Among them is the &lt;code&gt;servicePath&lt;/code&gt; identified using the &lt;code&gt;opera.io.webserver&lt;/code&gt; object. For more information about &lt;code&gt;opera.io.webserver&lt;/code&gt;, you can take a look at the &lt;a href="http://dev.opera.com/libraries/unite/docs/allclasses.dml"&gt;Opera Unite API&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Finally, we explicitly parse the template in order to proceed with the data binding before returning the template.
&lt;/p&gt;
&lt;p&gt;
&lt;h3&gt;templates/helloYusef.html&lt;/h3&gt;
&lt;p&gt;This is the final piece of the puzzle.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
&amp;lt;!doctype html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&amp;gt;
    &lt;title&gt;{{data.title}}&lt;/title&gt;
    &amp;lt;link
      rel="stylesheet"
      type="text/css"
      href="{{data.servicePath}}static/{{data.stylesheet}}"&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div&amp;gt;
        {{data.content}}
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
The Markuper template library outputs the page &lt;code&gt;templates/helloYusef.html&lt;/code&gt;, which is the page presented to your users. 
&lt;p&gt;
A special syntax is used to retrieve the JavaScript value bound to the template. For example &lt;code&gt;{{data.servicePath}}&lt;/code&gt; references the &lt;code&gt;servicePath&lt;/code&gt; value previously specified in helloYusef.js. 
&lt;/p&gt;

&lt;img src="http://devfiles.myopera.com/articles/790/helloYusef_screenshot.png" alt="say hello to Yusef" /&gt;
&lt;p class="comment"&gt;Figure 3: Hello Yusef example.&lt;/p&gt;

&lt;p&gt;There you have it. An Opera Unite application using the Yusef framework is created. You can download the source code of our &lt;a href="http://devfiles.myopera.com/articles/790/helloYusef.ua"&gt;helloYusef example&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="Summary"&gt;Summary&lt;/h2&gt;
&lt;p&gt;

&lt;p&gt;
In this article, we have introduced Yusef, Opera Unite’s Server Framework. There are three parts to Yusef, &lt;i&gt;section&lt;/i&gt; (which listens to a URL subpath), &lt;i&gt;action&lt;/i&gt; (which deals with form POST) and &lt;i&gt;plugin&lt;/i&gt;. 
&lt;/p&gt;
&lt;p&gt;
You can slowly increase the complexity by adding more plugins. One such interesting plugin is the Yusef UI plugin that ties together Opera Unite’s UI templating engine called &lt;a href="http://dev.opera.com/articles/view/markuper-unite-template-library/"&gt;Markuper&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
We will have a closer look at Yusef plugins in a future article.
&lt;/p&gt;

&lt;h2 id="Reference"&gt;Reference Materials&lt;/h2&gt;
&lt;p&gt; 
You might want to take a look at these other Opera Unite articles or libraries.&lt;/p&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://dev.opera.com/articles/view/opera-unite-developer-primer-revisited/"&gt;Opera Unite Development primer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://dev.opera.com/articles/view/markuper-unite-template-library/"&gt;Markuper template library&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://dev.opera.com/libraries/unite/"&gt;Opera Unite API&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://dev.opera.com/libraries/fileio/"&gt;File I/O API&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevOperaFullFeed/~4/ZKNYIcqNoKY" height="1" width="1"/&gt;</description>
<feedburner:origLink>http://dev.opera.com/articles/view/790</feedburner:origLink></item>
<item rdf:about="http://dev.opera.com/articles/view/783">
<creator>Stuart Colville</creator>
<dc:date>2009-09-23T10:56:18Z</dc:date>
<link>http://feedproxy.google.com/~r/DevOperaFullFeed/~3/g6_pUDhr0u4/783</link>
<title>Adding meaning to your HTTP error pages!</title>
<description>&lt;div class="article"&gt;&lt;h2&gt;Introduction&lt;/h2&gt;

&lt;p&gt;When searching for something on the web we’ve all had the experience of clicking on a link in a search engine’s results page only to find that the page no longer exists. If there’s no information on that page other than a default error message, the most likely course of action on the user’s part is to press the back button and try the next search result.&lt;/p&gt;



&lt;p&gt;As site authors we can make our error pages more meaningful to our users, so that an error becomes an opportunity to bring the user back into a site and show them content that’s relevant to what they’re looking for. In this article I’ll show you how to do just that.&lt;/p&gt;



&lt;p&gt;The contents of this article are as follows:&lt;/p&gt;



&lt;ul&gt;
&lt;li&gt;&lt;a href="#typical-http-error-codes"&gt;Typical HTTP error codes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#creating-a-custom-error-page"&gt;Creating a custom error page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#making-a-smarter-error-page"&gt;Making a smarter error page&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#search-engine-referrers"&gt;Search engine referrers&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#a-word-on-security"&gt;A word on security&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#providing-useful-routes-back-into-your-site"&gt;Providing useful routes back into your site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#handling-content-removal"&gt;Handling content removal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#bending-the-rules"&gt;Bending the rules for SEO&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#advanced-warning-of-problems"&gt;Advanced warning of problems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#pitfalls-to-avoid"&gt;Pitfalls to avoid&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#monitor-error-pages-carefully"&gt;Monitor error page resources carefully&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#ensure-the-correct-http-status-code-is-served"&gt;Ensure the correct HTTP status code is served&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#set-up-redirects-for-urls-that-have-changed"&gt;Set up redirects for URLs that have changed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#avoid-mystery-timed-redirects"&gt;Avoid mystery timed redirects&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#summary"&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;



&lt;h2 id="typical-http-error-codes"&gt;Typical HTTP error codes&lt;/h2&gt;



&lt;p&gt;For the purpose of this article we’re going to focus on creating pages for handling the following &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html"&gt;HTTP status codes&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;&lt;strong&gt;404&lt;/strong&gt;: When a page is not found by your webserver it will serve a &lt;code&gt;404 NOT FOUND&lt;/code&gt; status in its response headers. Along with the status code, most webservers are configured by default to display a basic page providing limited details of the error. The language used in these pages is often not particularly informative and tends to be overly technical.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;410&lt;/strong&gt;: A &lt;code&gt;410 GONE&lt;/code&gt; status is similar to the 404 page, except that it’s saying that the content has been deliberately removed. For example, you should return this status if a news article had to be removed for legal reasons.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;500&lt;/strong&gt;: A &lt;code&gt;500 Server Error&lt;/code&gt; page is shown when the server has a serious problem. Typical causes of 500 errors would be misconfiguration of the web server or a fatal error in server-side code. This page should always be static, because — depending on the cause of the error — you cannot guarantee that execution of server-side scripting  (such as calling separate include files or a redirection to another page) will be possible.&lt;/li&gt;

&lt;/ul&gt;

&lt;h2 id="creating-a-custom-error-page"&gt;Creating a custom error page&lt;/h2&gt;

&lt;p&gt;On any site it’s a good idea to create a design for your error pages so that the error pages fit into the overall design. If you don’t configure custom error pages, users will only see the default error page for the particular web server or framework you are using.&lt;/p&gt;

&lt;p&gt;Another good reason to override Apache’s default error pages is the fact that Internet Explorer displays its own internal error pages if the error page served is smaller than 512 bytes — and all of the default error messages are below this arbitrary threshold.&lt;/p&gt;

&lt;p&gt;All that’s needed for a custom page is to create an HTML document for each error that you want to handle and then configure your webserver or framework to use them in place of their defaults.&lt;/p&gt;

&lt;p&gt;For starters, any useful error page needs to provide a clear indication of what has happened, so that the user understands what went wrong. It’s best to avoid any technical jargon, as we want to avoid scaring users into reaching for the back button.&lt;/p&gt;

&lt;p&gt;The default apache error document reads as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Not Found

The requested URL /blah was not found on this server.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We as developers all know what a URL is, but would your granny? You should tailor the language of your error message to be understandable by your site’s audience, whether it is likely to be web geeks, or &lt;q&gt;normal&lt;/q&gt; people.&lt;/p&gt;

&lt;p&gt;An alternative version to this would be to use something a little more human, like this example used on google.com:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;The page - www.google.com/dkjfhsd - does not exist.

Suggestions:

* Check the spelling of the address you typed
* If you are still having problems, please visit the Help Center&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt; To get you started, here’s a simple example using Apache — don’t forget to make it look pretty. (If you’re lacking creative inspiration, &lt;a href="http://flickr.com/search/?q=404+page"&gt;Flickr&lt;/a&gt; can provide some ideas):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;

&lt;p&gt;Create your markup (feel free to reuse &lt;a href="404.html"&gt;my example&lt;/a&gt;)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"   
"http://www.w3.org/TR/html4/strict.dtd"&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Page Not Found&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;h1&amp;gt;Page not found&amp;lt;/h1&amp;gt;

  &amp;lt;p&amp;gt;The page you were trying to reach doesn’t exist. To continue on your journey please try one of the following:&amp;lt;/p&amp;gt;

  &amp;lt;ol&amp;gt;                
    &amp;lt;li&amp;gt;
      &amp;lt;!-- You could display the request url here but as always be sure to escape it correctly --&amp;gt;
      &amp;lt;p&amp;gt;Please check the url (web address) is correct; does it contain any spelling errors or typos?&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;If it does - please correct it in the address bar of your browser and hit enter&amp;lt;/p&amp;gt;
    &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;
      &amp;lt;!-- Provide a standard search box for your site --&amp;gt;
      &amp;lt;p&amp;gt;Try searching for the content you were looking for&amp;lt;/p&amp;gt;
      &amp;lt;form  method="GET" action="/search/"&amp;gt;
        &amp;lt;div&amp;gt;&amp;lt;!-- Using a div here as we don’t want a fieldset and legend for a search box --&amp;gt;
          &amp;lt;input name="q" value=""&amp;gt;
          &amp;lt;input type="submit" name="submit" value="Search"&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/form&amp;gt;
    &amp;lt;/li&amp;gt;
    &amp;lt;!-- if referrer is set you could set up a link to send them back to that  —  just be sure 
to not trust that data and make sure you’re not setting up a security hole in your site --&amp;gt;
    &amp;lt;li&amp;gt;Press the back button on your browser to return to the page you were previously on&amp;lt;/li&amp;gt;
  &amp;lt;/ol&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Save this page in the &lt;code&gt;htdocs&lt;/code&gt; folder of your Apache server installation&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Configure Apache to serve this page for 404 errors&lt;/p&gt;

&lt;p&gt;The main configuration file is usually called &lt;code&gt;httpd.conf&lt;/code&gt; or &lt;code&gt;apache2.conf&lt;/code&gt;, depending on the version of Apache you’re using.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ErrorDocument 404 /srv/awesome.com/htdocs/404.html&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you place the error document inside the main configuration folder as instructed above, then it will be the error page for every site and virtualhost on your server.  If you’d prefer to set up separate error pages for each virtualhost, you will need to place them inside the root folder of each virtualhost and specifically configure their individual &lt;code&gt;ErrorDocument&lt;/code&gt; directives. For detailed information on virtualhosts setup, see the &lt;a href="http://httpd.apache.org/docs/trunk/vhosts/"&gt;Apache vhosts Documentation&lt;/a&gt;.&lt;/p&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Restart Apache.&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;

&lt;p&gt;On most Linux systems — &lt;code&gt;sudo /etc/init.d/apache2 restart&lt;/code&gt;

&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;On Mac OS X — &lt;code&gt;sudo apachectl restart&lt;/code&gt;

&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;There are a few caveats when configuring the &lt;code&gt;ErrorDocument&lt;/code&gt; directive in Apache. If you specify a full URL for an error document, Apache will redirect the client to that location and the client will see the redirect status code rather than the original error page status code. This is something to be avoided as it’s extremely important to make sure error pages are served with the correct status code  — not doing so can confuse search engine robots.&lt;/p&gt;

&lt;h2 id="making-a-smarter-error-page"&gt;Making a smarter error page&lt;/h2&gt;

&lt;p&gt;So, if you follow the example above for all your different error codes, you’ll end up with a beautiful set of custom error pages that look a lot nicer than the defaults and that describe what the error really means to the user in a friendly way. Having done this, how can we make our error pages even better?&lt;/p&gt;

&lt;p&gt;First let’s look at making our error pages smarter for our users. Say a site visitor has come to our site looking for a particular piece of information and has hit the 404 page - what can we do to retain them?&lt;/p&gt;

&lt;h3 id="search-engine-referrers"&gt;Search engine referrers&lt;/h3&gt;

&lt;p&gt;A &lt;a href="http://en.wikipedia.org/wiki/Referrer"&gt;referrer&lt;/a&gt; is a header sent by the browser which tells a server the previous site the user was visiting. Like any data sent by the browser, we can’t trust it completely - but it can still be used to attempt to deduce some information about where a user has come from.&lt;/p&gt;

&lt;p&gt;Here’s an example of how to extract the keywords from a Google referral. An example google search URL looks like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;a href="http://www.google.co.uk/search?hl=en&amp;amp;amp;q=barista+champion&amp;amp;amp;btnG=Google+Search&amp;amp;amp;meta=" target="_blank"&gt;http://www.google.co.uk/search?hl=en&amp;amp;q=barista+champion&amp;amp;btnG=Google+Search&amp;amp;meta=&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Using an appropriate server-side function such as Python’s &lt;code&gt;urlparse&lt;/code&gt; module we can extract the relevant parts of the the query string:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; import urlparse
&amp;gt;&amp;gt;&amp;gt; url = "http://www.google.co.uk/search?hl=en&amp;amp;q=barista+champion&amp;amp;btnG=
Google+Search&amp;amp;meta="
&amp;gt;&amp;gt;&amp;gt; url_parts = urlparse.urlparse(url)
&amp;gt;&amp;gt;&amp;gt; url_parts
('http', 'www.google.co.uk', '/search', '',
'hl=en&amp;amp;q=barista+champion&amp;amp;btnG=Google+Search&amp;amp;meta=', '')&lt;/code&gt;&lt;/pre&gt;

&lt;div class="note"&gt;

&lt;p&gt;Note that in Python 2.5 &lt;code&gt;parse_qs&lt;/code&gt; is found in the &lt;code&gt;cgi&lt;/code&gt; module, eg:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; from cgi import parse_qs
&amp;gt;&amp;gt;&amp;gt; query_parts = parse_qs(url_parts[5])
&amp;gt;&amp;gt;&amp;gt; query_parts
{'q': ['barista champion'], 'btnG': ['Google Search'], 'hl': ['en']}
&amp;gt;&amp;gt;&amp;gt; terms = query_parts.get('q', None) and query_parts['q'][0].split()
&amp;gt;&amp;gt;&amp;gt; terms
['barista', 'champion']&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Also note that in Python 2.6 &lt;code&gt;parse_qs&lt;/code&gt; is found in the &lt;code&gt;urlparse&lt;/code&gt; module, eg:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; query_parts = urlparse.parse_qs(url_parts[4])
&amp;gt;&amp;gt;&amp;gt; query_parts
{'q': ['barista champion'], 'btnG': ['Google Search'], 'hl': ['en']}
&amp;gt;&amp;gt;&amp;gt; terms = query_parts.get('q', None) and query_parts['q'][0].split()
&amp;gt;&amp;gt;&amp;gt; terms
['barista', 'champion']&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Last, note that in Python 3.0 The entire &lt;a href="http://www.python.org/doc/2.6/library/urlparse.html?highlight=2to3"&gt;&lt;code&gt;urlparse&lt;/code&gt; module&lt;/a&gt; is moving to &lt;code&gt;urllib.parse&lt;/code&gt;; the &lt;code&gt;2to3.py&lt;/code&gt; script can update your code for you when you’re ready to move to Python 3.&lt;/p&gt;

&lt;/div&gt;

&lt;p&gt;If a user has come to our site from the results page of a search engine, we can look at the referrer and work out what search terms they had entered. We can then use those terms to search our site and provide a set of alternative content that matches those results. For instance,  you could feed those terms into your own search function and surface some relevant pages that might be of interest.&lt;/p&gt;

&lt;h4 id="a-word-on-security"&gt;A word on security&lt;/h4&gt;

&lt;p&gt;As with any other external source, it’s important to take care when making use of any data sent in a referrer, as you cannot trust this data  — a referrer header can easily be forged. If you are displaying anything on your site based on the referrer, it’s important to ensure that it’s correctly escaped to &lt;a href="http://en.wikipedia.org/wiki/Cross-site_scripting"&gt;avoid XSS vectors&lt;/a&gt;. If you are using referrer data to run queries against a database, you should also ensure that you correctly filter the data to avoid the possibility of an &lt;a href="http://en.wikipedia.org/wiki/Sql_injection"&gt;SQL injection attack&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id="providing-useful-routes-back-into-your-site"&gt;Providing useful routes back into your site&lt;/h3&gt;

&lt;p&gt;If a visitor didn’t land on your error page from a search engine’s results page, you have less to go on in terms of knowing what the the user was looking for. But never fear  —  there’s still plenty of approaches that can be used to engage the user.&lt;/p&gt;

&lt;p&gt;One possibility is to surface your site’s most popular content. For example, if you’re running an online shop then an obvious choice would be to provide links to the 10 most popular products on your site.&lt;/p&gt;

&lt;p&gt;Another approach is to provide a search box for users to use to find something relevant. It’s still worth looking at the referrer header, as you may be able to use a similar approach to that of the search engine referrer, which is to break apart the referring URL to feed a search. This will probably only work if your site is designed with nice URLs, eg:&lt;/p&gt;

&lt;pre&gt;&lt;a href="http://caffeineftw.com/news/2009-world-barista-championships" target="_blank"&gt;http://caffeineftw.com/news/2009-world-barista-championships&lt;/a&gt;&lt;/pre&gt;

&lt;p&gt;In this example, we can take the last part of the URL and split on the hyphen to get a nice set of search terms. We could also process out the &lt;a href="http://en.wikipedia.org/wiki/Stop_words"&gt;stop words&lt;/a&gt; such as &lt;q&gt;and&lt;/q&gt; and &lt;q&gt;to&lt;/q&gt;, but this may not be necessary if our site’s search capability already takes care of that.&lt;/p&gt;

&lt;p&gt;Here’s a very basic example of how we can break this down (again, in Python):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; url = 
'http://caffeineftw.com/news/2009-world-barista-championships'
&amp;gt;&amp;gt;&amp;gt; [ item for item in url.split('/') if item !="" ][-1].split('-')
['2009', 'world', 'barista', 'championships']&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So in this case we could feed our search with the following keywords:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;2009 world barista championships&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and present links to some likely matches on our 404 page, so that the user will almost certainly be brought back into looking around the site.&lt;/p&gt;



&lt;h3 id="handling-content-removal"&gt;Handling content removal&lt;/h3&gt;



&lt;p&gt;As briefly mentioned above, sometimes it’s necessary to explicitly remove content from a site, and a &lt;code&gt;410 GONE&lt;/code&gt; status should be served.&lt;/p&gt;

&lt;p&gt;Ideally your content management system will not actually delete content when it’s removed, but retain it in its data store and only make it unreachable for outside users, Assuming that you can still access the  original content behind the scenes, you can use that data and associated metadata in the 410 error page to once again feed a search or automatically find related content.&lt;/p&gt;

&lt;p&gt;As an example, you might have published an article about a celebrity wedding, which has then had to be removed due to legal reasons. The URL has now become a &lt;code&gt;410 GONE&lt;/code&gt; error page, but your server-side code can still use its knowledge of what used to be displayed on that addess and feed a search with any stored tags or other metadata, so that you can at least provide a list of related content for the uses.&lt;/p&gt;





&lt;h3 id="bending-the-rules"&gt;Bending the rules for SEO&lt;/h3&gt;



&lt;p&gt;Sometime it’s necessary to bend the rules and make what should be a 404/410 page a 200 OK. This is a technique used for &lt;abbr title="Search Engine Optimisation"&gt;SEO&lt;/abbr&gt; purposes when there’s lots of inbound links pointing a page that has been removed. In those special cases it can be useful to retain inbound traffic by essentially promoting a specialised error page in place of the previous content.                &lt;/p&gt;

&lt;h2 id="advanced-warning-of-problems"&gt;Pitfalls to avoid&lt;/h2&gt;

&lt;p&gt;Here’s a number of potential pitfalls to avoid when building smarter error pages.&lt;/p&gt;





&lt;h3 id="monitor-error-pages-carefully"&gt;Monitor error page resources carefully&lt;/h3&gt;

&lt;p&gt;If you’re adding searches fed by keywords extracted from referrers and historical metadata you want to keep a close eye on those pages, as delivering a smart error page will obviously use more resources than serving up a static page. To limit the resource hit, it’s worth thinking about caching search results for a limited time - that way, if you get a lot of errors in a short time due to a bad internal link, the load on the server is controlled.&lt;/p&gt;



&lt;h3 id="ensure-the-correct-http-status-code-is-served"&gt;Ensure the correct HTTP status code is served&lt;/h3&gt;

&lt;p&gt;A common mistake is to set up a custom error page, but to end up serving it with a &lt;code&gt;200 OK&lt;/code&gt; status code. This can be an issue if a search engine indexes your site, sees the &lt;code&gt;200 OK&lt;/code&gt; responses for what should be 404 or 410 error codes, and ends up indexing your actual error page. This will lead to listings for your company appearing with the error page content in the search results pages, instead of more meaningful content.&lt;/p&gt;

&lt;p&gt;Another thing to avoid is redirecting to an error page. If something is wrong you really should be serving the correct status code at the exact URL that was requested, not changing the URL.&lt;/p&gt;



&lt;h3 id="set-up-redirects-for-urls-that-have-changed"&gt;Set up redirects for URLs that have changed&lt;/h3&gt;

&lt;p&gt;In an ideal world all URLs would be permanent. However, in the real world there will always come a time where a URL has to be moved for some reason or another.&lt;/p&gt;

&lt;p&gt;If a 404 error is occurring because you’ve moved a page to a different URL then the correct way to handle that is to issue a &lt;code&gt;301 Moved Permanently&lt;/code&gt;, which instructs the browser to seamlessly take the user to the content’s new location. This header also helps to get the new location indexed by search engines, and the outdate URL to be replaced in their database with the new one (maintaining any keyword and search ranking you may already have had for the old address).&lt;/p&gt;

&lt;p&gt;Ideally, your content management tool should be automatically keeping track of pages you move and set up relevant &lt;code&gt;301 Moved Permanently&lt;/code&gt; redirect locations accordingly.&lt;/p&gt;



&lt;h3 id="avoid-mystery-timed-redirects"&gt;Avoid mystery timed redirects&lt;/h3&gt;

&lt;p&gt;At the time of writing the &lt;a href="http://yahoo.com"&gt;yahoo.com&lt;/a&gt; 404 page uses a meta-refresh to send users to their homepage after 10 seconds, but they also provide a search box on their 404! This means that you could be in the middle of typing a new search when you are redirected to the homepage without any prior warning — an annoying "feature" to avoid.&lt;/p&gt;





&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;

&lt;p&gt;In this article we’ve covered ways to build smart error pages that are designed to guide the user back into the site by showing them relevant content when something goes wrong. Doing this attempts to engage your audience and maximises the time they spend on your site without having them navigate back to a search results page.&lt;/p&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevOperaFullFeed/~4/g6_pUDhr0u4" height="1" width="1"/&gt;</description>
<feedburner:origLink>http://dev.opera.com/articles/view/783</feedburner:origLink></item>
<item rdf:about="http://dev.opera.com/articles/view/817">
<creator>Chris Mills</creator>
<dc:date>2009-09-16T06:00:05Z</dc:date>
<link>http://feedproxy.google.com/~r/DevOperaFullFeed/~3/gbAWuNnEWDA/817</link>
<title>A developer’s look at Opera Mini 5 beta</title>
<description>&lt;div class="article"&gt;&lt;h2&gt;Introduction&lt;/h2&gt;

&lt;div class="right"&gt;
&lt;img src="mini5ui.png" alt="opera mini 5 main ui" /&gt;
&lt;/div&gt;

&lt;p&gt;This article introduces &lt;a href="http://www.opera.com/mini/next/"&gt;Opera Mini 5 Beta&lt;/a&gt;, our cutting-edge mobile Web browser. Like previous versions, Opera Mini 5 beta works on most modern phones — from top of the range smart phones to feature phones.  In fact, it will run on almost any phone with a &lt;abbr title="Java Virtual Machine"&gt;JVM&lt;/abbr&gt;, showing regular web pages designed for desktop browsers without any problem, and reducing file sizes to save you time and money. Opera Mini is incredibly popular, being used worldwide by over 30 million users. Read our &lt;a href="http://www.opera.com/smw/"&gt;State of the Mobile Web Report&lt;/a&gt; for more detailed coverage of the mobile web industry, including a breakdown of Opera usage on mobile in different countries, what sites are popular on mobile, and other analyses.&lt;/p&gt;

&lt;p&gt;This article will briefly outline how Opera Mini 5 works and look at the new &lt;abbr title="User Interface"&gt;UI&lt;/abbr&gt; and features.  Then we’ll have a look at the user agent string and Opera Mini 5’s standards support, and we’ll touch on the optimizations you can make to improve web page compatibility with Opera Mini 5 and mobile web browsers in general.&lt;/p&gt;

&lt;p&gt;The table of contents is as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="#serverbased"&gt;Server-side rendering&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="#features"&gt;Opera Mini 5 new features&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="#standardssupport"&gt;Opera Mini 5 standards support&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="#uastring"&gt;Identifying Opera Mini 5: The user agent string&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="#optimizing"&gt;Optimizing for mobile&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="#summary"&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p class="note"&gt;Pick up your mobile phone and install the new &lt;a href="http://www.opera.com/mini/next/"&gt;Opera Mini 5 Beta&lt;/a&gt;, so you can play with it as you read through this article.&lt;/p&gt;

&lt;h2 id="serverbased"&gt;Server-side rendering&lt;/h2&gt;

&lt;p&gt;Opera Mini 5 is a thin-client application: when you use it to request a web page &lt;strong&gt;&lt;em&gt;(1)&lt;/em&gt;&lt;/strong&gt;, that request is sent off to a server-farm &lt;strong&gt;&lt;em&gt;(2)&lt;/em&gt;&lt;/strong&gt;; a proxy server receives the requested web page &lt;strong&gt;&lt;em&gt;(3)&lt;/em&gt;&lt;/strong&gt;, renders and reformats it, and then converts it to a light and efficient format developed by Opera called &lt;a href="http://dev.opera.com/articles/view/opera-binary-markup-language/"&gt;&lt;abbr title="Opera Binary Markup Language"&gt;OBML&lt;/abbr&gt;&lt;/a&gt; &lt;strong&gt;&lt;em&gt;(4)&lt;/em&gt;&lt;/strong&gt;. This is then sent to the Opera Mini client &lt;strong&gt;&lt;em&gt;(5)&lt;/em&gt;&lt;/strong&gt;, which displays it on the phone screen &lt;strong&gt;&lt;em&gt;(6)&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;img src="mini-render.png" alt="how opera mini works" /&gt;
&lt;p class="comment"&gt;Figure 1: The Opera Mini request–response workflow.&lt;/p&gt;

&lt;p&gt;As most of the complex processing is done on the server, Opera Mini 5 can run on relatively low-spec phones. In addition, the conversion to &lt;abbr title="Opera Binary Markup Language"&gt;OBML&lt;/abbr&gt; can reduce the file size by up to 90%, meaning that, where bandwidth is at a premium, you can save a lot of time and money.&lt;/p&gt;

&lt;p&gt;Note that, as all the processing is done on the server and what is to the client is a snapshot of the web page, some sites that feature heavy Ajax functionality or background scripting may not behave quite like you’d expect. However, most sites will function without a problem — you can find out more about Opera Mini 5’s standards support later on in the article.&lt;/p&gt;

&lt;h2 id="features"&gt;Opera Mini 5 new features&lt;/h2&gt;

&lt;p&gt;Opera Mini 5 has a bold new look and many exciting features, and comes with support for both touch and non-touch screen phones. The new &lt;abbr title="User Interface"&gt;UI&lt;/abbr&gt; was designed by Opera’s fabulous designers — see Figure 2.&lt;/p&gt;

&lt;img src="mininewui.png" alt="Opera Mini 5 Speed Dial and tabs" /&gt;
&lt;p class="comment"&gt;Figure 2: The Opera Mini 5 UI with Speed Dial and tabs.&lt;/p&gt;

&lt;p&gt;As you can see, Opera Mini now features tabs as well as Speed Dial thumbnails. Note that in this beta release, Opera Link is disabled.&lt;/p&gt;

&lt;p&gt;You can display pages using either regular desktop view, in which you can scroll around the page and zoom in and out, or in Mobile view, where the whole page is reformatted to a single column. The latter tends to work better for devices with narrow screens.&lt;/p&gt;
&lt;h2 id="standardssupport"&gt;Opera Mini 5 standards support&lt;/h2&gt;

&lt;p&gt;Opera Mini 5 now uses the &lt;a href="http://www.opera.com/docs/specs/presto22/"&gt;Opera Presto 2.2&lt;/a&gt; rendering engine, bringing its display capabilities in line with &lt;a href="http://www.opera.com/mobile/"&gt;Opera Mobile 9.7 beta&lt;/a&gt; and &lt;a href="http://www.opera.com/browser/"&gt;Opera 10&lt;/a&gt; for desktop. This means that you can take advantage of the same standards support on Opera Mini 5 as on its desktop cousin, with a few small exceptions: HTML 5 Forms and Web Fonts are not supported, and the blur effect on text-shadows and SMIL animations are also disabled. The majority of JavaScript functions are available, except those that require asynchronous operations or user interaction once the page has been loaded. Note that plug-ins, such as Adobe Flash, are not supported.&lt;/p&gt; 

&lt;p&gt;The vast majority of readers will be familiar with common web standards usage, but we’ll still cover some of Opera Mini 5 beta’s more interesting supported features:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;p&gt;&lt;strong&gt;CSS 3 Media Queries&lt;/strong&gt;. These allow you to dynamically optimize CSS layouts and styling depending on device attributes such as screen width and height. See the &lt;a href="http://dev.opera.com/articles/view/opera-mini-5-developer-preview/#mediaqueries"&gt;Media Queries&lt;/a&gt; section for an example.&lt;/p&gt;&lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;CSS 3 colors: RGB(A) and HSL(A)&lt;/strong&gt;. Opera Mini 5 also now supports the &lt;abbr title="Red Green Blue (Alpha)"&gt;RGB(A)&lt;/abbr&gt; and &lt;abbr title="Hue Saturation Lightness (Alpha)"&gt;HSL(A)&lt;/abbr&gt; color models outlined in the &lt;a href="http://www.w3.org/TR/css3-color/"&gt;CSS 3 Color Module&lt;/a&gt;. You can find more details about these color models in our &lt;a href="http://dev.opera.com/articles/view/color-in-opera-10-hsl-rgb-and-alpha-transparency/"&gt;Color in Opera 10 — HSL, RGB and Alpha Transparency&lt;/a&gt; article.&lt;/p&gt;

&lt;p&gt;Have a look at our &lt;a href="rgba-hsla.html"&gt;RGB(A)/HSL(A) example&lt;/a&gt; using Opera Mini 5. You’ll see a series of tables with individually-colored cells, to demonstrate the effect of iterative increases to the different channels in the two color models.&lt;/p&gt;
&lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;CSS 3 Selectors&lt;/strong&gt;: Opera Mini has support for all the selectors listed in the &lt;a href="http://www.w3.org/TR/css3-selectors/"&gt;CSS 3 Selectors Module&lt;/a&gt;. We have created a typical &lt;a href="css3selectors.html"&gt;zebra-striped playlist table&lt;/a&gt; that makes use of the &lt;code&gt;nth-child&lt;/code&gt; pseudo-selector and a CSS 3 attribute selector. Have a look at the source code to see what is going on. There are a number of &lt;a href="http://dev.opera.com/articles/view/zebra-striping-tables-with-css3/"&gt;Dev.Opera CSS articles&lt;/a&gt; that cover many of these selectors in detail, and you can find a lot more good information on CSS 3 selectors and other features at &lt;a href="http://css3.info"&gt;CSS3.info&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;&lt;strong&gt;SVG&lt;/strong&gt;: Opera Mini 5 supports &lt;abbr title="Scalable Vector graphics"&gt;SVG&lt;/abbr&gt;. You can try it out by loading &lt;a href="operaicon6.svgz"&gt;this SVG based Opera logo&lt;/a&gt; in Opera Mini 5 beta.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p class="note"&gt;You can find more details about standards support in Opera Presto 2.2 on the &lt;a href="http://www.opera.com/docs/specs/presto22/"&gt;Web specifications supported in Opera Presto 2.2&lt;/a&gt; page, and additional examples in our recently published &lt;a href="http://dev.opera.com/articles/view/the-opera-10-experience/"&gt;Opera 10 article&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="uastring"&gt;Identifying Opera Mini 5: The user agent string&lt;/h2&gt;

&lt;p&gt;A browser can be recognised by its user agent string.  Opera Mini 5 identifies as &lt;code&gt;Opera 9.8&lt;/code&gt;, with &lt;code&gt;Opera Mini/5.x&lt;/code&gt; included in the parentheses. Its default user agent string is as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Opera/9.80 (J2ME/MIDP; Opera Mini/5.0.2056/866; U; en) Presto/2.2&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It is important to bear in mind that phone manufacturers and mobile carriers often customize their browser’s user agent strings, so sniffing for an exact match to any particular user agent string doesn’t always yield the desired results.  The &lt;code&gt;Opera Mini/5.x&lt;/code&gt; portion of the string should always be included, where &lt;code&gt;x&lt;/code&gt; is the minor version number. Also note that in general, Opera can be identified by using JavaScript to test for the &lt;code&gt;window.opera&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;We’d like to advise that, where possible, you shouldn’t test for browsers or features and serve different content. Instead, you can make your sites work well across a variety of devices and screen sizes using Web standards and Media Queries. The following section has more details.&lt;/p&gt; 

&lt;h2 id="optimizing"&gt;Optimizing for mobile&lt;/h2&gt;

&lt;p&gt;In this section we will look at specific techniques and tips for optimizing pages for mobile viewing.&lt;/p&gt;

&lt;h3 id="mediaqueries"&gt;Media Queries&lt;/h3&gt;

&lt;p&gt;With all the devices of different shapes and sizes on the market, you can’t guarantee what screen size your web site will be viewed on – so design your layouts to be fluid and robust, and use Web Standards and Media Queries to dynamically optimize for different screen sizes.&lt;/p&gt;

&lt;p&gt;Media Queries are a CSS 3 feature that allow you to specify under what conditions a style sheet should be applied. They are applied using the &lt;code&gt;@media&lt;/code&gt; at-rule, a media type, and optional expressions that limit the scope of the style sheet. For instance, to limit a style sheet to only apply to a screen which is 480px or less, you could use the following Media Query: &lt;/p&gt;


&lt;pre&gt;&lt;code&gt;@media screen and (max-device-width: 480px) {  
  // insert CSS rules here
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After the &lt;code&gt;@media&lt;/code&gt; declaration, you first list the media types that this block of rules applies to. After that you can optionally define a series of expressions which set further condition on when the rules should be applied. In the example we’re limiting the scope of the style rules with &lt;code&gt;max-device-width&lt;/code&gt; – this tests the physical width of the screen.  You can also use &lt;code&gt;max-width&lt;/code&gt;, which on a desktop browser would test the width of the browser window, but on mobile browsers checks the width of the virtual viewport. A list of supported media features can be found in the &lt;a href="http://www.opera.com/docs/specs/presto22/css/mediaqueries/"&gt;Opera Presto 2.2 Media Queries spec&lt;/a&gt;.  Media Queries are also supported by recent versions of WebKit and Gecko.&lt;/p&gt;
 
&lt;p&gt;Let’s have a look at a &lt;a href="http://dev.opera.com/articles/view/opera-mini-5-beta-developers/mediaquery3.html"&gt;Media Queries example&lt;/a&gt;, as seen in Figure 3.&lt;/p&gt;

&lt;img src="mediaqueryexample1.png" alt="media query example on desktop" /&gt;
&lt;p class="comment"&gt;Figure 3: Media Query example on desktop.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@media screen and (min-width: 480px) {
  .content p:before  {
    content: "You are now using the styling designed for screen. ";
    font-weight: bold;
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The Media Query works in the same way as described above, but tests for a minimum width, via the &lt;code&gt;min-width&lt;/code&gt; media feature. If the condition is met, the rules inside the block are applied.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@media handheld, screen and (max-width: 480px),
       screen and (max-device-width: 480px)  {
  .content p:before  {
    content: "You are now using the styling designed for
              handhelds or devices with &amp;lt; 480px screens. ";
    font-weight: bold;
  }

  div.sidebar, div.content {
    width: auto;
    float: none;
    margin: 0;
    padding: 0.5em;
  }
}&lt;/code&gt;&lt;/pre&gt;

 
&lt;p&gt;The second Media Query includes three expressions.  The CSS in this block is applied if any of these expressions are true:&lt;/p&gt;
&lt;ul&gt;
 
&lt;li&gt;The browser identifies itself as a handheld via the &lt;code&gt;handheld&lt;/code&gt; media type. Opera Mini and Mobile ignore this unless they are switched to the Mobile View by the user.&lt;/li&gt;
 
&lt;li&gt;The browser window width or virtual viewport is 480 pixels or less.&lt;/li&gt;
 
&lt;li&gt;The screen width of the device is 480 pixels or less&lt;/li&gt;
 
&lt;/ul&gt;
 
&lt;p&gt;To see the Media Query in action, view this example on Opera Mini 5, and try it on Opera 10 desktop and reduce the width of the browser window below 480 pixels - see Figure 4.&lt;/p&gt;

&lt;img src="mediaqueryexample2.png" alt="media query example on opera mini 5 and desktop with a small width" /&gt;
&lt;p class="comment"&gt;Figure 4: The Media Query example running on Opera Mini 5 beta, and on Opera 10 desktop with a narrow window width.&lt;/p&gt;



&lt;h3 id="tips"&gt;Other tips and caveats&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Mobile devices in general have less memory and CPU speed than their desktop counterparts. Think carefully about how memory-intensive your web applications are, and optimize them as much as possible. Battery life is an important constraint on mobile, so avoid intensive use of JavaScript and especially &lt;abbr title="XmlHttpRequest"&gt;XHR&lt;/abbr&gt;.&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;
  &lt;p&gt;Make sure your site is usable both via keyboard and mouse. Mobile phones can come with spatial navigation, virtual mouse pointers and touch input, and your web application should work in all these scenarios.&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;Keep text entry to a minimum, as entering text is far more awkward on mobile than on desktop. For example, where possible, allow your users to select options from a list rather than entering them as free-form text.&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;
  &lt;p&gt;In case you decide to create a separate mobile-specific version of your site, make sure that users can still easily reach the full desktop version and set it as their default via a cookie or profile preference.&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;As a final point, it is a good idea to test your site in a number of mobile browsers and devices, even if it is just to get some familiarity with the different contexts in which users view your site.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find more tips on designing for mobile browsers in our &lt;a href="http://dev.opera.com/articles/view/introduction-to-the-mobile-web/"&gt;Introduction to the mobile web&lt;/a&gt; article.&lt;/p&gt;


&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;

&lt;p&gt;We hope you’ve enjoyed this overview of &lt;a href="http://www.opera.com/mini/next/"&gt;Opera Mini 5 beta&lt;/a&gt;. We’ve taken you through its main new features and exciting new web standards support. As always, let us know how you like it!&lt;/p&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevOperaFullFeed/~4/gbAWuNnEWDA" height="1" width="1"/&gt;</description>
<feedburner:origLink>http://dev.opera.com/articles/view/817</feedburner:origLink></item>
</rdf:RDF>
