A PHP Helper for Pinned Sites on Windows 7 and Internet Explorer 9

This PHP helper will provide a site with a digital footprint on the Windows 7 taskbar by enabling the pinned sites feature with static and javascript jumplists when a page is pinned. The advanced and dynamic features of pinned sites cannot be provided with a simple helper such as this one. All this helper does is set up the shortcut, window, and jumplists features of a pinned site.

Microsoft Pinned Site Features
Microsoft Pinned Site Features Overview

Windows 7 treats an Internet domain as a first class citizen by giving web developers access to modify the way the browser appears when opening a pinned site, as well as modifying the context menu with links. When you integrate with Internet Explorer 9 using javascript you have the ability to show an icon overlay on the pinned shortcut, flash the taskbar shortcut entirely to show the user that your site needs some attention, add more jump list items in a new category, and provide live notifications to the context menu by altering the javascript jumplist. You even have the ability to change the thumbnail button bar icons and handle click events for them. If you want to provide the best user experience for your Internet Explorer 9 users you must learn about pinned sites.

Pinning a site to the taskbar can be done a couple of ways. Firstly, a user can drag a tab or the favicon next to the address bar from Internet Explorer 9 to the taskbar and it will automatically pin itself. You could include a graphic on the page and make it draggable by setting the img, and then dragging that to the taskbar on the bottom of the screen. You cannot, unfortunately, pin a site to the taskbar programmatically – it must be associated with a user interaction.

You could add the site to the Start->All Programs menu with a javascript function “window.external.msAddSiteMode();”. But that site shortcut is not in a pinned state – its added. You don’t automatically get a nice sub menu without explicitly right clicking on the newly created menu item and choosing to pin it to the start menu. That’s when you’ll get a nice menu item with the sub menu that you defined when you click the start menu and hover over the shortcut. I added a function to the helper that will add an a tag with the onclick attribute set to that function anyway, every little bit helps

Tasks Menu
Microsoft Pinned Site Tasks Menu

Most of the more advanced features of pinned sites are implemented in javascript. However, the static features of pinned sites are implemented using special meta tags defined by Microsoft. You use static meta tags inserted into the html of the page to populate the Tasks jumplist and set up all of the window settings. The window settings of pinned sites are: shortcut name, tooltip, starturl, navigation button color, and window size.The shortcut name is used as the name of the shortcut when used anywhere else, when used on a pinned site it is shown in the tooltip when hovering over the shortcut. The tooltip is used as the tooltip for the shortcut when not used on the taskbar. The starturl is the page that is opened up by default when clicking on the pinned shortcut. Using the starturl setting in this way enables you to keep a consistent interface when using the feature on multiple pages, just keep in mind that the window settings should be the same on every page. The navigation button color can be any named or hex color. A 24 x 24 version of the favicon is placed to the left of these buttons to provide a branded experience to the user. The window size it basically the initial width and height of the window that opens up. When a user resizes the window, those settings are remembered by Windows and used instead.

I’m not certain, but I believe Microsoft designed pinned sites using meta tags as a fallback for all of those IE users that do not trust javascript running in their browser. In any case, the design makes it simple to add the static pinned site features to any webpage by inserting special meta tags in the page heading. Granted, you can’t put your sitemap in the context menu using static features. But you can put the five most useful links inside the context menu that open up in in a domain branded window using only meta tags.

The icon of the pinned site’s shortcut is the favicon of the page that’s pinned. On Windows 7 the favicon is king for domains. Its the graphic that represents your domain to the user and it should be looking as best as it can. If your site is using a graphic format other than .ico for your shortcut icon change it. All the other browsers can handle .ico files and Windows won’t replace it with the infamous blue e globe shortcut icon on the system. When pinning a site, the system is going to be looking for 32 x 32 .ico file and if it can’t find it the system will frame the 16 x 16 .ico (yuck). You best bet would be to go to one of those free icon generator sites that output layered .ico files (http://www.rw-designer.com/image-to-icon – custom sizes = 16,32,64,128) and upload a 128 x 128 gif (for the transparancy) of your logo and let it generate a layered .ico file for you. Doing this you’ll get all four sizes used by the different Windows systems for shortcuts packed into the one .ico file and its out of the way – proper graphics everywhere. However, if you’re uncomfortable with the increased file size of your icon you should at least include a 16 x 16 and a 32 x 32 layer in your outputted icon (http://www.rw-designer.com/image-to-icon – custom sizes = 16,32). Microsoft stated :Recommended: 16×16, 32×32, 48×48 and Optimal: 16×16, 24×24, 32×32, 64×64 as layered icon sizes for pinned sites in the documentation (http://msdn.microsoft.com/en-us/library/gg131029%28v=vs.85%29.aspx). The choice is up to you in the end. I do know Windows will do its best to resize the existing graphics where it can but its probably better to go with one of the Microsoft recommendations in the end.

Pinned Site Window
Pinned Site Window Customization

As I mentioned previously, when you pin a site to the taskbar or Start->All Programs menu a special branded “version” of Internet Explorer 9 will automatically open up and close the previous unpinned IE window. Internet Explorer 9 needs to do that to set up the shortcut menu. The meta tags and javascript on that page is evaluated and the context menu is created behind the scenes. The context menu will persist after you close the window, so don’t link to anything that relies on the application state.
The menu items that are shown when you right click on a pinned site shortcut are implemented in two different ways. There are five slots in the Tasks heading that are implemented with meta tags. You are also allowed to create a second jump list and category in javascript that appears above the Tasks jump list with ten additional jump list items by default. Internet Explorer only allows one jump list category other than the Tasks jump list. Each menu item is represented with three pieces of data: the label text of the menu item, the action uri that is opened when the menu item is clicked, and the icon uri that points to a 16 x 16 icon .ico file hosted somewhere on your server. So, to sum it up, you get a total of fifteen menu items; five reserved for static tasks, and another ten under the heading of your choice – not bad at all.

Huffington Post Pinned Menu
Huffington Post Pinned Menu

Notes on items in the jumplists: addresses can point anywhere, not just to addresses inside your domain. When adding items to the javascript jumplist they must be coded last first in javascript for proper placement (my helper fixes that). Microsoft states: “The Jump List is designed primarily for dynamic tasks that change as the user interacts with your application” in reference to the javascript jumplist. All my helper does is set up the shortcut and adds links to it – there is no dynamic features implemented. If you want more than a list of links, such as icon overlays or a dynamic jumplist, you will have to write that in yourself with javascript. In actuality the javascript jumplist can contain twenty items, only ten are visible by default. It could be considered unreasonable to ask a visitor to change any operating system setting, that’s why I only mentioned ten items previously.

To see the other ten invisible items on the javascript jumplist you’ll have to change the settings for the taskbar. Right-click the Start menu and click Properties. On the Start Menu tab, click the Customize button to open the Customize Start Menu dialog box. Change the Number of recent items to display in Jump Lists option to a number that fits your needs. Click OK to close the dialog box.

Obviously, being able to point to fifteen different places on your site when someone right clicks a shortcut in the operating system is a wonderful thing. It can retain users on your site and make them happier at the same time. However, there’s more to pinned sites than what this helper provides and implementing those features could improve site usage and user retention even further. Microsoft provides some reasonable statistics on Pinned Sites usage here: http://windowsteamblog.com/ie/b/ie/archive/2011/02/10/internet-explorer-9-hits-rc-milestone.aspx that may give you a bit more insight.

Amazon Pinned Site Menu
Amazon Pinned Site Menu

This helper is pretty simple to use. You create a helper object by passing in the six window settings. You then populate the Tasks jumplist by calling the add_meta_task method for every task you add, passing in the item text, item url, and item icon url for each. If you want more than the five links that the Tasks jumplist provides you have to create a javascript jumplist by calling the create_js_jumplist method and passing it the category label text. Then add the items to it by calling the add_js_jumplist_item method for each link, again passing in the item text, item url and item icon url for each. You can add up to twenty items, but only ten will show by default. Then you echo the object out wherever you want the meta tags and script block to appear.

Whether you need a jump start on implementing the pinned sites feature on your site or if you just want to have a bunch of links available to your visitors when they pin your site, this helper can help make you life a little easier by providing a simple way of getting your pinned site up and running quickly.

.

.

.

.

.

.

.

;^>

Ie9_helper usage example


<?php
require_once 'Ie9_helper.php';
?>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <?php
        $ie = new Ie9_helper("IE 9 Test", "IE 9 Test", "http://somedomain/ie9test.php", "Red", 530, 600);
        $ie->add_meta_task("Home Page", "http://somedomain/index.php", "http://somedomain/images/favicon.ico");
        $ie->add_meta_task("Some Other Page", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        // up to 5 meta tasks like above
		// now try the js list
        $ie->create_js_jumplist("New JS Jump List");
        $ie->add_js_jumplist_item("item1", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item2", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item3", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item4", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item5", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item6", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item7", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item8", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item9", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item10", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        // MS says 10 are shown by default but 
		// you can add 20 in case the user changes settings
        $ie->add_js_jumplist_item("item11", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item12", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item13", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item14", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item15", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item16", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item17", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item18", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item19", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        $ie->add_js_jumplist_item("item20", "http://somedomain/ie9test.php", "http://somedomain/images/favicon.ico");
        
        echo $ie;
        ?>
        <title>IE 9 Test Page</title>
        <link rel="shortcut icon" href="http://somedomain/images/favicon.ico" >
        
    </head>
    <body>
        <?php
        echo $ie->add_to_all_programs_menu();
        ?>
    </body>
</html>

Ie9_helper.php source


<?php

/**
 * Ie9_helper
 * A class that automates some of the Internet Explorer 9 integration features for
 * pinned sites. Basically creates all of the static meta tags required to make a site pinnable.
 * Has the method to create the javascript jumplist and method to add items to it.
 * Should test for IE9 before creating this object.
 * @author Timothy Tocci    timtocci at ymail dot com
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 * @version 0.2
 * @link https://timothytocci.wordpress.com/2011/12/23/a-php-helper-for-pinned-sites-on-windows-7-and-internet-explorer-9/
 */
class Ie9_helper{
    private $jsjl_created;  // is the list category created?
    private $tasks = array();   // used for the static task array (jump list)
    private $listcat;   // only one defined list category
    private $jsitemarr = array();   // used for the js array (dynamic jump list)
    private $mtags = array();   // used for the initial meta tag array (props of the pinned site)    
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Code below allows for dynamic property assignment - good for experimenting    
    // - allows you to assign values to properties that doesn't exist (makes php more js like)
    protected $dynprops = array();  // array that holds dynamically assigned properties
    // magic method that gets a previously assigned dynamic property - better have a value
    public function __get($property) {
        return $this->dynprops[$property];
    }
    // magic method that defines a new dynamic property
    public function __set($property, $value) {
        $this->dynprops[$property] = $value;
        return true;
    }
    // -------------If not experimenting just chop this code block out------------------------------------//
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    /**
     * __construct
     * this constructor sets up the initial pinned site object
     * @param string $shortcut_name - name of the shortcut (like you're ever gonna see it)
     * @param string $tooltip - tooltip that shows when you hover over shortcut
     * @param string $starturl - startup url for shortcut - this opens up when you click on it
     * @param string $color - the color of the navigation buttons (named color or hex css2.1 / 3)
     * @param integer $width - INITIAL width of window - user resize overrides
     * @param integer $height  - INITIAL height of window - user resize overrides 
     */
    public function __construct($shortcut_name, $tooltip, $starturl, $color, $width, $height) {
        $this->jsjl_created = false;
        $this->set_shortcut_name($shortcut_name);
        $this->set_shortcut_tooltip($tooltip);
        $this->set_start_url($starturl);
        $this->set_navbutton_color($color);
        $this->set_window_size($width, $height);        
    }
    
    /**
     * __toString
     * magic method used to turn the object into an insertable string. Lists out all
     * of the meta tags held in the $mtags and $tasks arrays - then adds the items
     * in the $jsitemarr inside script tags
     * @return string to insert into doc
     */
    public function __toString() {
       $temp="\n" . "<!-- ie pinned site -->" . "\n";
        foreach ($this->mtags as $value) {
            $temp .= $value . "\n";
        }
        if(count($this->tasks) > 0){
            foreach ($this->tasks as $value) {
                $temp .= $value . "\n";
            }
        }
        if(count($this->jsitemarr) > 0){
            $temp .= "<script type='text/javascript'>" . "\n";
            $temp .= $this->listcat . "\n"; 
            $this->jsitemarr = array_reverse($this->jsitemarr); // fixes the last first problem
            foreach ($this->jsitemarr as $value) {
                $temp .= $value . "\n"; // js item
            }
            //
            $temp .= "</script>" . "\n";
        }
        $temp .= "<!-- end ie pinned site -->" . "\n";
        return $temp;
    }
    
    /**
     * create_js_jumplist
     * creates the javascript jumplist - add items with  add_js_jumplist_item
     * @param string $Jump_list_title
     * @return boolean success
     */
    public function create_js_jumplist($Jump_list_title) {
        $this->listcat = "window.external.msSiteModeCreateJumplist('$Jump_list_title');";
        $this->jsjl_created = true;
        return true;
    }
    
    /**
     * add_js_jumplist_item
     * adds a javascript ite to the javascript jumplist Note: fixes the last first
     * problem with javascript jumplist (if altering the js jumplist with js remember
     * that items are added to the menu last first)
     * @param string $item_text -  menu label text
     * @param string $item_uri - action url
     * @param string $item_icon_uri - address of .ico file shown in menu
     * @return boolean success
     */
    public function add_js_jumplist_item($item_text, $item_uri, $item_icon_uri){
        if($this->jsjl_created == false){
            return false;
        }
        $this->jsitemarr[] = "window.external.msSiteModeAddJumpListItem('$item_text', '$item_uri', '$item_icon_uri');";
        return true;
    }
    /**
     *  get_task_metatag
     * returns a meta tag for the page that defines a task link inside a pinned
     * site menu. Only five of these static jump links are allowed on a pinned site.
     * @param string $task_name - name on the pinned site menu
     * @param string $task_action_uri - web page that opens up
     * @param string $task_icon_uri - 16 x 16 icon on the pinned site menu (.ico)
     * @return string  - contains the meta tag
     */
    private function get_task_metatag($task_name, $task_action_uri, $task_icon_uri) {
        $metatag = "<meta name='msapplication-task' content='name=$task_name;action-uri=$task_action_uri;icon-uri=$task_icon_uri'/>";
        return $metatag;
    }

    /**
     * add_meta_task
     * used to add static jump list tasks to the object that appear in the pinned site
     * right click context menu each with a different name, url, and icon.
     * Only five of these static meta tags are allowed on a 
     * page. Any item in the jump list should have identical meta tags in the page heading for
     * consistency.
     * @param string $task_name - name on the pinned site menu
     * @param string $task_action_uri - web page that opens up
     * @param string $task_icon_uri - 16 x 16 icon on the pinned site menu
     * @return boolean success
     */
    public function add_meta_task($task_name, $task_action_uri, $task_icon_uri) {
        $this->tasks[] = $this->get_task_metatag($task_name, $task_action_uri, $task_icon_uri);
        return true;
    }

    /**
     * add_to_all_programs_menu
     * method creates the link needed to add the site to the start menu. Could call
     * the msAddSiteMode() method from within javascript as an alternative.
     * @param string $shortcut_text
     * @return string containing the link html 
     */
    public function add_to_all_programs_menu($shortcut_text  = 'Add To Start Menu - All Programs' ){
        $atag = "<a onclick='window.external.msAddSiteMode();' href='#'>$shortcut_text</a>";
        return $atag;
    }
    
    /**
     * set_shortcut_name
     * creates the meta tag that holds the shortcut name for the pinned site
     * and inserts it into the private $mtags array
     * @param string $shortcut_name
     * @return boolean success
     */
    private function set_shortcut_name($shortcut_name){
        $meta = "<meta name='application-name' content='$shortcut_name'/>";
        $this->mtags[] = $meta;
        return true;
    }
    
    /**
     * set_shortcut_tooltip
     * creates the meta tag that holds the tooltip for the pinned site shortcut
     * and inserts it into the private $mtags array
     * @param string $tooltip
     * @return boolean success
     */
    private function set_shortcut_tooltip($tooltip){
        $meta = "<meta name='msapplication-tooltip' content='$tooltip'/>";
        $this->mtags[] = $meta;
        return true;
    }
    
    /**
     * set_start_url
     * creates the meta tag that holds the pinned site startup url
     * and inserts it into the private $mtags array
     * @param string $starturl
     * @return boolean success
     */
    private function set_start_url($starturl){
        $meta = "<meta name='msapplication-starturl' content='$starturl'/>";
        $this->mtags[] = $meta;
        return true;
    }
    
    /**
     * set_navbutton_color
     * creates the meta tag that sets the navigation button color
     * and inserts it into the private $mtags array
     * @param string $color
     * @return boolean success
     */
    private function set_navbutton_color($color){
        $meta = "<meta name='msapplication-navbutton-color' content='$color'/>";
        $this->mtags[] = $meta;
        return true;
    }
    
    /**
     * set_window_size
     * creates the meta tag that sets the initial width and height of
     * pinned site window and inserts it into the private $mtags array
     * Windows will remember the user's resize so keep in mind that this is 
     * only for the initial setting.
     * @param integer $width
     * @param integer $height
     * @return boolean success
     */
    private function set_window_size($width, $height){
         $meta = "<meta name='msapplication-window' content='width=$width;height=$height'/>";
        $this->mtags[] = $meta;
        return true;
    }
}

Advertisements

One thought on “A PHP Helper for Pinned Sites on Windows 7 and Internet Explorer 9

  1. Everyone loves what you guys tend to be up too.
    This type of clever work and coverage! Keep up the very good works guys I’ve incorporated you guys to my blogroll.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s