How to transform HTML, CSS and images in mobile conpatible way.


Three different main CSS files are needed for mobile sites

  • common.css used on every handset
  • highend.css used on WebKit and Gecko based browsers (iPhone, Android, Nokia Series 60, Maemo)
  • lowend.css used on crappy browsers (Opera Mini, all proprietary underpowered browsers out there)

The condition determining how good your browser is comes from mobile.heurestics.simple module and is based on the browser user agent sniffing.

Desktop visuals trick

Because you end up developing and viewing your site on the desktop browser in any case, the following trick is used to clip the site width to certain dimensions to prevent ugly mobile sites on wide screen aspect rations.

This is in gomobiletheme.basic/static/common.css:

#margins {
    margin-left: auto;
    margin-right: auto;
    background: white;

 * Do not look stupid on desktop browsers.
 * If screen width is too wide, clip displayable area to 800 px.
@media screen and (min-device-width: 850px) {
        #margins {
           -webkit-box-shadow: 0 0 4px black;
            -moz-box-shadow: 0 0 4px black;
            box-shadow: 0 0 4px black;
            max-width: 800px;

More info

Rewriting HTML

WYSIWYG edited HTML must be transformed to be mobile compatible

  • All <img> tags are "mobilized" by putting them through a mobile image resizer
  • Other HTML fixes are applied, possible to make HTML XHTML compatible

This all is based on processing HTML code with lxml DOM library.

Go Mobile Basic Theme does this by default for Document (Page) content type.

The following snippet will rewrite "text" HTML code if the site is rendered in mobile mode:

<tal:rewrite-html define="text context/getText; helper nocall:context/@@mobile_image_html_rewriter; text python:helper.processHTML(text, only_for_mobile=True)">
    <div tal:replace="structure text" />

The following snippet will force of rewriting "text" HTML code:

<tal:rewriteimg define="helper nocall:context/@@mobile_image_html_rewriter; text python:helper.processHTML(text)">
       <div tal:replace="structure text" />

It is also possible force safe HTML (clean up <script> etc.).

The following snippet will make "safe" HTML in Python code:

def clean_html(context, request, html):
    from zope.component import getMultiAdapter

    mobile_image_html_rewriter = getMultiAdapter((context, request), name="mobile_image_html_rewriter")
    return mobile_image_html_rewriter.processHTML(html, trusted=False, only_for_mobile=False)

See also

  • for other options

Image resizing

Resizing traversable images

You can resize images that accessible in Zope by traversing their path, or any URL.

You can generate necessary image URLs by using the following:

from import IMobileImageProcessor
from mfabrik.behaviorutilities.viewutils import getSiteRootRelativePath

mobile_image_processor = getMultiAdapter((self.context, self.request), IMobileImageProcessor)

# How image should be resized
properties = {
    "width" : "auto",
    "padding" : 10,
    "conserve_aspect_ration" : "true",

# Site root relative path to the traversable ImageField payload
path = getSiteRootRelativePath(self.campaign, self.request)
path = path + "/campaignVideoThumbnail"

# Return <img> src attribute URL which puts the image through mobile resizer
# Path could be also absolute URL to an image on an external server
self.image_url = mobile_image_processor.getImageDownloadURL(path, properties)

In the case you specify absolute URL, the image will be downloaded and resized when the HTTP request is made to render the image. The resized copy is cached.

Resizing non-traversable objects

You can put through arbitary image objects through image resizer by using the following code:

# Use templates directory to search for templates.

# Viewlets are active only when gomobiletheme.basic theme layer is activated

class MobileHeaderImageResizer(grok.CodeView):
    """ A special mobile-resize aware renderer for header images.

    We cannot use stock resizer as images
    are stored in annotation storage which is untraversable.

    def render(self):

        # This will read image from Archetypes ImageField called "campaignImage"
        field = self.context.getField("campaignImage")
        value = field.get(self.context)

        params = {
                  "image" : value,
                  "width" : "auto",
                  "padding_width" : 10,
                  "cache_key" : "campaign_header_image",
                  "conserve_aspect_ration" : True,

        helper = self.context.unrestrictedTraverse("@@mobile_image_processor_helper")

        # This will call
        # and output HTTP response payload to download the image
        return helper(params)

For more information see module source code.

Resizer parameters

Parameters are lsited in

width: "auto" or pixels. Default: "auto".

height: "auto" or pixels. Default: "auto".

padding_width: How many pixels reduced from the determined with. Default: 0.

converse_aspect_ration: True of False. Default: True.

url: Absolute URL to image (http://), or path relative to the site root

image: Image object. Only useful if you subclass ResizerHelperView or use it directly. Accepts
any Zope image object which can be decoded by gomobile.imageinfo.

cache_key: String. Something which identifies the image object if URL is not given. You can use context id, site id or similar here, combined with view id.