No matter how you feel about the iPhone, you cannot deny that this phone has captured a good piece of the mobile device market. And, in my opinion, it was he who gave the opportunity to
normally use the Internet from the phone. But although the built-in safari is complete (thanks,
Webkit ), many people want to make a special version of the iPhone site that looks like a real iPhone app (for example,
iweather.yandex.ru ).


One of the most popular libraries for creating an adapted version of the site is
iUI .
Cooking
First you need to make a special mime type by writing it in initializers / mime_types.rb:
Mime::Type.register_alias "text/html", :iphone
Now the erb-templates for the site will be called as * .iphone.erb (for example, index.iphone.erb).
You also need to write a before filter in ApplicationController, which will switch the site versions:
before_filter :adjust_format
def adjust_format
request.format = :iphone if iphone_request?
end
def iphone_request?
request.subdomains.first == "iphone"
end
There is one subtle point - you need to decide when you want to display the iphone version of the site. I chose to switch to the domain for myself, but no one bothers you to determine the iPhone by the HTTP_USER_AGENT header and not bother with the domains.
IUI basics
We are done with preparations, we are starting to create an iphone version of the site. On the website
iUI download the latest version of the library. Unfortunately, the documentation on iUI is rather scanty, in fact limited to a couple of examples of sites - open source has its drawbacks :-).
Installing iUI consists of copying scripts, styles (iui * or iuix * files - the minimized version) and images into the corresponding directories of the site.
Making a new erb template (applitation.iphone.erb):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta id="viewport" name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
<title>@page_title</title>
<%= stylesheet_link_tag 'iui' %>
<%= javascript_include_tag 'iui' %>
</head>
<body>
<div class="toolbar">
<h1 id="pageTitle"></h1>
<a id="backButton" class="button" href="#"></a>
</div>
<%= yield %>
</body>
</html>
In iUI, an unusual approach to navigation is that a page can be divided into several “screens” (physically, the screen is the root div or ul), the one who contains the selected parameter is considered active, and only that one is displayed. It looks like this:
<ul title="" selected="true">
<li><%= link_to " ", shoplist_path(current_user.shoplist), :target => "_self" %></li>
<li><%= link_to " ", "#recipes" %></li>
</ul>
<ul id="recipes" name="recipes">
<li><%= link_to "", recipes_path(:order => "date"), :target => "_self" %></li>
<li><%= link_to "", recipes_path(:order => "quality"), :target => "_self" %></li>
<li><%= link_to "", recipes_path(:order => "popular"), :target => "_self" %></li>
</ul>
When loading, the first list will be displayed, by clicking on the “all recipes” link, the screen will be changed to the second list (corporate iPhone scrolling). In order for the external link to work correctly, the target attribute needs to be set to "_self".
')
Form implementation
Now login page (app / views / sessions / new.iphone.erb):
<% form_tag sessions_path, :id => "auth", :name => "auth", :class => "panel", :selected => "true", :title => "", :target => "_self" do -%>
<script>
function toggleSession() {
document.auth.foreign_computer.value = (document.auth.foreign_computer.value == "1") ? "0" : "1";
}
</script>
<fieldset>
<div class="row">
<label> :</label>
<%= text_field_tag 'login' %>
</div>
<div class="row">
<label>:</label>
<%= password_field_tag 'password' %>
</div>
<div class="row">
<label> iPhone?</label>
<div class="toggle" onclick="toggleSession()" toggled="true">
<span class="thumb"></span>
<span class="toggleOff"></span>
<span class="toggleOn"></span>
</div>
<input type="hidden" name="foreign_computer" id="foreign_computer" value="0" />
</div>
</fieldset>
<%= submit_tag '' %>
<% end -%>
A normal checkbox does not steer, whether to remember a session is done with a proprietary switch (see fiction with div.toggle and javascript: toggleSession ()) :-). By the way, pay attention, the class “panel” makes the background of the page as in the settings of our mobile phone.
Link Customization - ajax screen update
Anyone who has not yet closed the browser, will tell you more about the links. Links in iUI are made quite cleverly, complete with target = "_ replace", which allows you to create a loadable list (
working example ). But, as is often the case, there are not enough standard tools - I wanted to make a transition from the list to a specific object without loading a new page, so that I could go back to the list, and it was in
its original state. For these purposes, I modified the clicker in iui.js, adding a new target:
addEventListener("click", function(event) {
...
else if (link.target == "_custom_replace")
{
link.setAttribute("selected", "progress"); //
// ajax
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (req.readyState == 4) {
//
var frag = $(link.getAttribute("target_elem"));
frag.innerHTML = req.responseText;
//
setTimeout(unselect, 1000, true);
//
iui.showPageById(link.getAttribute("target_elem"));
}
};
req.open(link.getAttribute("target_method") || "GET", link.href, true);
req.send(null);
}
...
}
I made the list of objects as follows:
<% if @first_page? %>
<ul title="" selected="true">
<% end %>
<% @recipes.each do |recipe| %>
<li>
<%= link_to recipe.name, recipe_path(recipe), :target => "_custom_replace", :target_elem => "recipe" %>
</li>
<% end %>
<% if @page < @recipes.total_pages %>
<li><%= link_to " ...", params.merge(:page => @page+1), :target => "_replace" %></li>
<% end %>
<% if @first_page? %>
</ul>
<% end %>
<% if @first_page? %>
<div id="recipe" name="recipe" class="panel"/>
<% end %>
This list is loadable, “digg-styled”, and the return from the page of the object to the list works, and works
correctly , i.e. returning the user sees the list in the state in which it was left.
Conclusion
iUI is a handy tool for developing an iPhone version of the site, allowing you not to be distracted by the layout, and at the same time it is easily customized to the needs of the developer. In fact, this is a js + css + pack of pictures, so you can use it regardless of the language and framework of the system being developed.
The results of my work can be viewed on
iphone.livecookbook.ru (authorization form, list of objects, “shopping list”), the described
list of recipes is available without authorization. Modified iui.js is also easily
available .