Tag Archive for 'iphone'

07
Mar

OmniFocus Coming For The iPhone

Finally:

A few hours ago, Apple announced the iPhone SDK! We’re still trying to download it (Apple’s servers are overloaded), but it looks like it has all the features we were hoping for.

We’re eager to get started on our first iPhone app—and, yes, that first app will be… OmniFocus.

… via the Omni Mouth Blog.

04
Mar

Dynamically Loading Symfony Applications Via Subdomains

The concept of “Symfony applications” is sometimes confusing for those new to Symfony, but they can be a very powerful way to break up the functionality of a project. The classic example for this separation is the “front end” and “back end” or “back office” applications. The idea here being that the front-end will be what the normal user sees and he back-end being what the administrator of the site uses to maintain the site through an admin interface. Since these two applications are in the same Symfony project, they can share certain common elements (such as database configurations and schemas), but they can have their own modules and templates. In essence, each application can provide a different “view” of the same data.

If you only have one application, you’re probably content with the way Symfony automatically sets up your first application to use the default index.php controller, but what happens when we add applications? You’ll notice that Symfony adds controllers for each application in the web directory, so you might end up with a set of files like this:

web/index.php
web/frontend_dev.php
web/backend.php
web/backend_dev.php

… assuming you have a “frontend” and “backend” application. Also, note that since we created the “frontend” application first, Symfony automatically used the index.php filename for what would have been called frontend.php.

So, this means that when we view our site at www.mysite.com/ the frontend application is loaded and when we view www.mysite.com/backend.php we get the backend application. This is fine for most uses, but what if we could streamline this a bit so that applications were loaded based on a sub-domain?

That’s exactly what we’ll do.

Setting It Up

First, we’ll rename our index.php file to frontend.php (this will be useful later on) and create a new, blank index.php controller in its stead. Our controllers should now be as follows:

web/index.php (blank!)
web/frontend.php
web/frontend_dev.php
web/backend.php
web/backend_dev.php

Open up the newly created index.php file. We’re going to add a little bit of our own logic here so that Symfony dynamically loads the correct application based on what’s set in the sub-domain:

<?php
// define the standard symfony environment constants
define('SF_ROOT_DIR',    realpath(dirname(__FILE__).'/..'));
define('SF_ENVIRONMENT', 'prod');
define('SF_DEBUG',       false);

// get the domain's parts
list($tld, $domain, $subdomain, $subdomain2) = array_reverse(explode('.', $_SERVER['HTTP_HOST']));

// determine which subdomain we're looking at
$app = ($subdomain == 'staging') ? $subdomain2 : $subdomain;
$app = (empty($app) || $app == 'www' ) ? 'frontend' : $app;

// determine which app to load based on subdomain
if (!is_dir(SF_ROOT_DIR.'/apps/'.$app))
{
    define('SF_APP','frontend');
}
else
{
    define('SF_APP',$app);
}

require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.
'config'.DIRECTORY_SEPARATOR.'config.php'); // Should be on one line, with the above text
sfContext::getInstance()->getController()->dispatch();

Note: I generally use a “staging” sub-domain for testing on the production server before pushing to the actual production site, so you’ll notice that I check for this sub-domain separately. This is so I can use something like backend.staging.mysite.com and still load the correct back-end application. Feel free to simply remove that step if you want your staging sub-domain to point to an actual Symfony application for some reason.

This controller file should look familiar to you as it’s just a bit of a reworking of a default controller. We simply added some logic to detect a subdomain, check if it’s a valid application and then, if it is, we have Symfony load it dynamically. You’ll notice that instead of using frontend.mysite.com for the front-end we simply check for www or an empty sub-domain field and set the application to “frontend” by hand. If your default application name is something different, you’ll have to change this.

Some Notes About This Method

Firstly, you should know that this method will only work if you have the correct sub-domain addresses as DNS records pointing to your server (or if you have wildcard DNS set up so that anything.yoursite.com is sent to your server).

Also, for clean URL rewriting on each sub-domain, don’t forget to set no_script_name to “on” in each application’s settings.yml file for the “prod” environment:

prod:
  .settings:
    no_script_name:           on

… this allows our sub-domains to use URLs in the form backend.mysite.com/module/action instead of backend.mysite.com/index.php/module/action. This is usually disabled by default for all but the first application you create (in our case, frontend).

Also, remember that file we renamed to frontend.php? Well, we did that for a reason. In previous articles, I’ve stated why I like setting up local development environments, so I won’t go into detail here, but you’ll notice with this method we can still access the frontend application directly by typing something like mysite.dev/frontend.php which may be useful for testing purposes. You could even create an index_dev.php that loads the dev environment for our custom front controller if you needed to. Note though, that I’m specifically not including support for a “dev” sub-domain (or anything that loads the dev environment) since the dev controllers should not live on your production server!

So What?

You might be wondering what all the fuss is about. Why go through the trouble of setting up these dynamic sub-domains linked to Symfony applications? Well, as with many things, necessity is the mother of invention: for a project I’m working on right now, I needed to add an iPhone/iPod Touch specific site to an existing Symfony project. A separate Symfony application makes perfect sense since it will simply be a different view for the same data. It would have been easy enough to just use the default mysite.com/iphone.php controller, but I wanted it to be a separate sub-domain because it just feels better separating it out that way, and you get nice clean URLs and an easy to remember iPhone-specifc domain name to boot.

In another article, I’ll be publishing some tips for incorporating this method into a site that automatically detects an iPhone or iPod Touch and reacts accordingly.

19
Jan

Quick Tip: Symfony and the iPhone WebClip Bookmark Icon

According to the Apple docs, you need to create a 57x57 PNG, name it “apple-touch-icon.png” and upload it to the root of your web directory in order for the iPhone to find and use your icon.

What I found more useful though, was that this can be overridden using a link attribute, similar to the way favicons are handled. This allows us to use symfony’s standard “images” directory to house the icon. So, the head of our layout.php could be updated with the addition of:

<link rel="apple-touch-icon" href="<?php echo image_path('apple-touch-icon') ?>" />

… which would make it look something like this:

webclip example

Note: as this is a post on symfony, I’m using symfony’s built-in image_path helper, but this can be simply href="/images/apple-touch-icon.png" if you’re not into that.

Taking it a Step Further

The way the real power of symfony gets leveraged is when you want to have different icons for different sections of your site. Let’s say you wanted to have a different touch icon related to every different module in your symfony project. Symfony makes this really simple to do. Replace the existing link tag we made earlier with something like this:

<?php if (file_exists(sfConfig::get('sf_web_dir').'/images/webclip_icons/'.$sf_context->getModuleName().'.png')): ?>
    <link rel="apple-touch-icon" href="<?php echo image_path('webclip_icons/'.$sf_context->getModuleName()) ?>" />
<?php else: ?>
    <link rel="apple-touch-icon" href="<?php echo image_path('webclip_icons/apple-touch-icon') ?>" />
<?php endif ?>

Basically, this code just checks to see if there’s a Web Clip icon with the same name as the current module in /images/webclip_icons and if it finds it, it links to that one instead of the default one.

Of course, this is just an example of how powerful and easy this is. This idea could be extended in many different ways.

More Info

You can read more about iPhone development at Apple’s iPhone Dev Center. One of the more useful pages on that site is the one on Designing Content.

Also, as noted elsewhere, you seem to get a crisper icon if you use a 60x60 image at 72 DPI.