Author: Nick Belhomme

IE8 Accelerator Tutorial

Goal of this article

This article will describe what a accelerator is and how to implement one for Internet Explorer 8 (IE8).

What is a accelerator

According to answers.com ‘to accelerate’ means : ‘To increase the speed of’; ‘To reduce the time required’.
And that is exactly what Microsoft intended. Imagine yourself reading a webpage about an hotel and you want to know where the hotel is located. We used to select the address text, copy it, go to our favorite locator, http://maps.live.com, http://maps.google.be, paste it and press go. This took a lot of time, and was a repetitive task.

I said "was" because Microsoft has automated this process for us. To accelerate our productivity and to make it really convenient, they allow the user (that’s us) to install accelerators (webservices). Take the above scenario. We want to know the location of the hotel. We select the address and then automagically a blue button appears. Clicking this blue button let you select your accelerator of choice. In this case the maps. Hovering on "live maps" will give you an immediate preview on the location without you having to leave the page. If you click , you will be redirected towards the maps.live.com website with the address already searched for you and in display. No more copying and pasting anymore, just selecting and picking your accelerator.

If you want to see it in action check out this awesome video explaining the feature: http://mschnlnine.vo.llnwd.net/d1/mix/8/1/5/IE8Activ_mix.mp4 (takes a while to load, just be patient)

Creating an Accelerator is easier than you think

To create one the only thing you need is a page where you host your accelerator definition. And a webservice that is available to use. Let’s create ourselves a blog.nickbelhomme.com search.

First we need a service. Luckily for us, this service already exist!
http://blog.nickbelhomme.com/index.php?s=php

So we’ll be using this one. What we need next is an accelerator definition.

The accelerator definition

The definition is an xml file.

<?xml version="1.0" encoding="UTF-8"?>
<os:openServiceDescription
    xmlns:os="http://www.microsoft.com/schemas/openservicedescription/1.0">
    <os:homepageUrl>http://blog.nickbelhomme.com</os:homepageUrl>
    <os:display>
        <os:name>Search Nick's Blog</os:name>
        <os:icon>http://blog.nickbelhomme.com/favicon.ico</os:icon>
        <os:description>Search on the Nick's Blog</os:description>
    </os:display>
    <os:activity category="Search">
        <os:activityAction context="selection">
            <os:execute action="http://blog.nickbelhomme.com/index.php" method="get">
                <os:parameter name="s" value="{selection}" type="text" />
            </os:execute>
        </os:activityAction>
    </os:activity>
</os:openServiceDescription>

Most of it is self explanatory so the only thing I am going to discuss is this part:

    <os:activity category="Search">
        <os:activityAction context="selection">
            <os:execute action="http://blog.nickbelhomme.com/index.php" method="get">
                <os:parameter name="s" value="{selection}" type="text" />
            </os:execute>
        </os:activityAction>
    </os:activity>

category="Search"

Accelerators are grouped by function so that users can quickly access the task that they want. You can set the default Accelerator for a given category when you install the Accelerator or through the Manage Add-ons dialog box. Examples of services that exist today:

  • Add: del.icio.us, Digg, Reddit
  • Blog: Windows Live Spaces, Windows Live Writer, Blogger
  • Define: Encarta, Wikipedia, Dictionary.com
  • Map: Windows Live Map, Google Maps, Yahoo! Maps, MapQuest
  • Send: Windows Live Mail, Gmail, Yahoo! Mail
  • Translate: Windows Live Translation, AltaVista’s Babel Fish, Google Translation

We have added our custom one: Search

os:execute

In the action parameter we define the uri of the webservice and in the method we define the communication method: post or get.
In this os:execute container we can define as many parameters as we want, but we can only have access to 1 dynamic parameter and that is {selection}. Whatever the user selects will be used here. So if he would select "php" the os:parameter name=s would get a value of php.

I hope this is clear. And congratulations you just build your first accelerator.

The attentive reader was probably already dying to get an answer to the question: "but what about preview screens?" Well I am glad you ask. Let’s get into that now!

Adding a preview

Adding a preview screen to the definition is as simple as adding 1 line. Let’s see if you can find it.

<?xml version="1.0" encoding="UTF-8"?>
<os:openServiceDescription
    xmlns:os="http://www.microsoft.com/schemas/openservicedescription/1.0">
    <os:homepageUrl>http://blog.nickbelhomme.com</os:homepageUrl>
    <os:display>
        <os:name>Search Nick's Blog</os:name>
        <os:icon>http://blog.nickbelhomme.com/favicon.ico</os:icon>
        <os:description>Search on the Nick's Blog</os:description>
    </os:display>
    <os:activity category="Search">
        <os:activityAction context="selection">
            <os:preview action="http://blog.nickbelhomme.com/index.php?s={selection}" /> 
            <os:execute action="http://blog.nickbelhomme.com/index.php" method="get">
                <os:parameter name="s" value="{selection}" type="text" />
            </os:execute>
        </os:activityAction>
    </os:activity>
</os:openServiceDescription>

I’ll bet you found it:

<os:preview action="http://blog.nickbelhomme.com/index.php?s={selection}" /> 

Adding this line, automagically enables the preview window.
However if you try out this piece of code, you will see that the entire page is loaded into the small preview window. This is not what we want, so we will have to create a new page. Sepcifically designed to fit the preview window. Creating such a page should be very standard for you.
Having a page specifically designed to fit the preview box gives us complete control on what to show to the user when he sees the preview window.

Installing

To allow the user to install an accelerator is as easy as providing the user a button, or link with a onclick event.

<button id="myButton"
    onclick="window.external.AddService('http://blog.nickbelhomme.com/accelerator')">
    add Search Nick's Blog</button> 

Add this piece of code somewhere a user would click it and IE8 will give them an alert box with the request for installation.

”’Attention”’: It seems like you need to define a new category in order to have two different accelerators using the same root domain. This means when you want to install multiple accelerators from one page, you will have to define a different category for each of them. Instead of Search => Search Nick, Search Resume, …

<os:activity category="Search Resume">

Possible selections

VARIABLES          CONTEXT      DESCRIPTION
===========================================
{documentUrl}      All          The href of the document. 
{documentTitle}    All          The title of the document, if available. 
{documentDomain}   All          Effective second-level domain from the document's href. 
{documentHost}     All          Fully qualified domain from the document's href. 
{selection}        selection    Currently selected text. 
{link}             link         The href of the selected link. 
{linkText}         link         The innerText of the selected link. 
{linkRel}          link         The rel of the selected link, if available. 
{linkType}         link         The type of the selected link, if available. 
{linkDomain}       link         Effective second-level domain from the link's href. 
{linkHost}         link         Fully qualified domain from the link's href.

A few things to remember about variables:

  • Always enclose variable names in curly braces {}; for example {selection}. To specify a literal curly brace character in the request, escape it with a backslash, such as \{{selection}\}.
  • Placing a "?" after the variable name indicates that it is optional; for example, {documentTitle?}.
  • If any required (non-optional) variable in the URL template is not available (for example, trying to execute an Accelerator that includes {linkRel} in the action attribute against a link with no rel attribute) the Accelerator cannot be executed and its entry in the shortcut menu is dimmed.
  • If any os:parameter element has an empty value for any reason, it will not appear in the request.

Facebook Example using multiple selections

<?xml version="1.0" encoding="utf-8"?> 
<openServiceDescription xmlns="http://www.microsoft.com/schemas/openservicedescription/1.0"> 
    <homepageUrl>http://www.facebook.com</homepageUrl> 
    <display>  
        <description>Share web content with your Facebook friends.</description>  
        <name>Share on Facebook</name>  
        <icon>http://www.facebook.com/favicon.ico</icon> 
    </display> 
    <activity category="Share"> 
        <activityAction context="selection">  
            <execute method="get" action="http://www.facebook.com/share.php">  
                <parameter name="src" value="iea"/>  
                <parameter name="u" value="{documentUrl}"/>  
                <parameter name="t" value="{selection}" />  
            </execute> 
        </activityAction> 
        <activityAction context="document">  
            <execute method="get" action="http://www.facebook.com/share.php">  
                <parameter name="src" value="iea"/>  
                <parameter name="u" value="{documentUrl}"/>  
                <parameter name="t" value="{documentTitle}" />  
            </execute> 
        </activityAction> 
        <activityAction context="link">  
            <execute method="get" action="http://www.facebook.com/share.php">  
                <parameter name="src" value="iea"/>  
                <parameter name="u" value="{documentUrl}"/>  
                <parameter name="t" value="{linkText}" />  
            </execute> 
        </activityAction> 
    </activity>
</openServiceDescription>

Preview Window from Ebay

the accelerator definition: http://www.ieaddons.com/nl/DownloadHandler.ashx?ResourceId=1444 (check the source)
the preview code: http://ie8.ebay.com/activities/preview/index.php?query=ipod (check the source)

More Information

http://msdn.microsoft.com/en-us/library/cc289775(VS.85).aspx

Ok that are two tutorials in two days. Now it is up to you!
Have fun.
Nick Belhomme

Webslice for IE8 Tutorial

Goal of this article

This article will describe what a webslice is and how to implement one for Internet Explorer 8 (IE8).

What is a webslice

Web Slices are snippets of the entire web page that a user can subscribe to.
Web Slices will be kept updated by the browser automatically, and can be viewed directly from the Favorites bar, complete with graphics and visuals.

Developers can mark parts of the pages as Web Slices, using the hAtom and hSlice microformat.
For the end user it has the same functionality has for instance a google weather widget.

Internet Explorer 8 Webslice
Internet Explorer 8 Webslice

What is a microformat

Like we said before a webslice is added by using microformats. Webslices use the hAtom microformat specification. You already have a lot uses for microformats available today. Think of the hCard microformat which uses the hAtom specification.
An example of a vcard is:

<div class="vcard">
   <div class="fn">Joe Doe</div>
   <div class="org">The Example Company</div>
   <div class="tel">604-555-1234</div>
   <a class="url" href="http://example.com/">http://example.com/</a>
</div>

as you can see there are specific class names in the code. Vcard indicates the microformat is a hcard microformat and all special classnames inside this container are considered special. Everything speaks for itself, fn (firstname), org (organisation), …

The purpose of these microformats is to make it easy for the end user. He can for instance download the vcard directly into his address book by the click of a button. This way he does not have to copy and paste everything into the right fields of his address book.

Want to read more about this? Read the great article on : http://blog.batchblue.com/not-just-another-technology-microformats-can-actually-help-you/.

If you want a live example, install the firefox Operator addon https://addons.mozilla.org/nl/firefox/addon/4106 and visit my website at http://www.nickbelhomme.com.
Now click on my contact information and you will see in the operator toolbar: contactpersons 1. Here you can download my contact information with a click of a button!

Microsoft saw a missing functionality in Rss and wanted to make their users give all the info needed at their fingertips. So they combined a kind of RSS functionality with the microformat specification. And voila they introduced their own microformat specification hslice.

The hslice specification better known as a webslice

So microsoft wanted to make a hybrid between rss readers and microformats. And they succeeded and it works perfectly!

The hslice (webslice microformat specification) exists out of only 6 special strings of which 2 are mandatory(!):

*hslice !
*entry-title !
*entry-content
*feedurl
*endtime
*ttl

So let us dive right in starting with the container: hslice

hslice

The browser has to know which part of the webpage it can extract as a webslice. So we need to give it an indicator. This is done by placing the hslice on the container tag (div, p, …). And we do this as followed:

<div id="mywebslice" class="hslice">
    <span>Nick Belhomme</span>
    <p>
        My name is Nick Belhomme And I am 30 years old
        and I am from <span> Aarschot</span>
    </p>
</div>

As you can see we have added a class with the name of hslice. Also note the id we gave the webslice. The id is a necessity. Without it the webslice will not be found. This is because every webslice should have a unique identifier!

The container for the webslice is created. Now we have to add a title.

entry-title

Every webslice should have a title to be displayed in the favorites bar of IE8.

in the example of above we want the following title: “Nick Belhomme Aarschot”
To accomplish this we will have to put entry-title in the code.

<div id="mywebslice" class="hslice">
    <span class="entry-title">Nick Belhomme</span>
    <p>
        My name is Nick Belhomme And I am 30 years old
        and I am from <span class="entry-title"> Aarschot</span>
    </p>
</div>

As you can see we have placed 2 entry-title class names in the piece of code. This is not necessary, only one will do. But we wanted the title to be Nick Belhomme Aarschot. So we had to add 2. We now have a valid webslice, but it has no content making it useless. So let’s add it.

entry-content

First we have to decide what we want the user to see. Because the container containing the class=”entry-content” attribute will be shown. In the example of above we could place the entry-content on the opening div next to hslice, but that will make our example saying 2 times Nick Belhomme. Which is not what we want. So we are going to put it on the p tag. Besides Why do you think I put the p tag there in the first place? ๐Ÿ™‚

<div id="mywebslice" class="hslice">
    <span class="entry-title">Nick Belhomme</span>
    <p class="entry-content">
        My name is Nick Belhomme And I am 30 years old
        and I am from <span class="entry-title"> Aarschot</span>
    </p>
</div>

And now we have a fully working webslice! If you have a webpage with this piece of code in it. IE8 will check it every 15 minutes for updates. As this is static no updates will ever occur, but put some php behind it and let my age change and you have yourself a dynamic webslice.
But wait? What about feedurl??!! You are right, lets get into that now!

feedurl

Internet Explorer 8 does regular checks to see if the webslice has new content and is there for updated.

To do this it reloads the entire page containing the webslice and then extracts it. As you can imagine this process is slow, especially on a big page. So the hslice specification allows alternative content for updates. We specify the alternative content by adding an anchor tag

<div id="mywebslice" class="hslice">
    <a rel="feedurl" href="http://nickbelhomme.com/mywebsliceUpdate" style="display:none;"></a>
    <span class="entry-title">Nick Belhomme</span>
    <p>
        My name is Nick Belhomme And I am 30 years old
        and I am from <span class="entry-title"> Aarschot</span>
    </p>
</div>

As you can see, we do not use feedurl as a class name but as a value to the rel attribute. You can however use it as a classname.
The attentive reader also noticed we removed the entry-content from the code. This is not necessary because it will be ignored, but it is good practice to keep your code as clean as possible.
The link will not show in the webpage because we have hidden it with inline styling. Now let’s see how the update page should look like.

The Update and display Page

Microsoft specifies the update page as a RSS xml feed. There are a few restrictions to keep in mind:
* You cannot use javascript
* You cannot use external style sheets. Only inline styles are supported.
* All the hslice classes that are mandatory should also be on that page.

The Standalone Update page
<rss version="2.0" >
<channel>
  <title>Nick Belhomme Aarschot</title>
  <link>http://www.nickbelhomme.com</link>
  <description>About page</description>
  <ttl>60</ttl>
  <item>
    <title>Nick Belhomme</title>
    <link>http://www.nickbelhomme.com</link>
    <description><![CDATA[
<div>
    <span>Nick Belhomme</span>
    <p>
        My name is Nick Belhomme And I am 30 years old
        and I am from <span> Aarschot</span>
    </p>
</div>
]]></description>
  </item>
</channel>
</rss>

But wait? Does this mean I cannot use JS or CSS? Of course not, you can! However this requires an additional page.
However you should NOT use the rss feed structure from the Update page standalone. Just write the update page in plain old HTML!
Instead of writing a container tag with the entry-content class to represent the content we will tell the webslice to fetch the display page from another url which can contain all the stuff you want.
How do we link the display page in the update page? Easy:

The Update page which uses a display page
<div id="mywebslice" class="hslice">
    <a rel="entry-content" href="http://nickbelhomme.com/mywebsliceDisplay" style="display:none;"></a>
    <span class="entry-title">Nick Belhomme</span>
</div>

As you can see we use the entry-content in an anchor tag and specify the page in the href attribute.

The display page

Just a plain old html webslice. Here you can include js files, css files and stuff.
Like I said before this display page is not necessary if you do not want to use external style sheets or javascript. If not you can use the update page as a standalone. If you do want to use css and js, the combination is the solution.

endtime

This name tells the browser that the webslice will not be used anymore after a specific time (in Universal Time Code (UTC)).

Think of a webslice we could develop for Tour de France. After the tour is over, the webslice will not be updated anymore and thus is useless: How do we set the expiration date?

<abbr class="endtime" title="2008-04-29T17:50:00-08:00"></abbr>

ttl

By default IE8 will check for an update on your webslice every 15 minutes. You can redefine how many times the update should occur, but never quicker than 15 minutes! The setting is in minutes. And in the example of below we wait 60 minutes before the next update is checked.

<p style="font-size:xx-small">Updated every <span class="ttl">60</span> minutes.</p>

Of course as with all the other stuff, you can put a display none on this to hide it from the display.

More Info

Check out Microsoft tutorial pages: http://msdn.microsoft.com/en-us/library/cc956159(VS.85).aspx
and this awesome video explaining the feature: http://mschnlnine.vo.llnwd.net/d1/mix/8/1/5/IE8Activ_mix.mp4 (takes a while to load, just be patient)

Now it is your turn, have fun creating webslices,
Nick Belhomme

Seven Things – Tagged by Michelangelo van Dam

Ok I was tagged by Michelangelo van Dam and thus let me share 7 things you do not know about me.

Although it is not necessary to comply with this tagging game, I will use this tagging game linked to the seven deadly sins.
So be prepared to enter my mind. And a beautiful mind it is. (Jeps guilty on pride)

Lust

Giving into lust can lead to sexual or sociological compulsions and or transgressions. But what about my lust for writing good PHP?
There is nothing sexual about that? Or is it?!! It can boost my ego whenever I have that ahaa-moment when writing code.
Adrenaline rushes through my body and I want to code some more. Feeling very energetic after that piece of code has been written.
Ready to do some happy dancing, and as we all know dancing is sexual.

Gluttony

Meaning to gulp down, swallow. Gluttony is the over-indulgence and over-consumption of anything to the point of waste.
I never experienced this. I am hungry, very hungry to learn more on a non-stop basis. I gulp down, swallow information like you
wouldn’t believe. Sometimes I think my nickname should be the human sponge as my brain tends to pick up everything it finds
interesting and rarely lets go.

Greed

I love money, I love lots of it. But not from a greedy point of view but from a giving point of view. The more I have the more
I can share with the world. Greed is something I cannot know. My life philosophy just doesn’t allow this. I give away ten percent Of what I earn to good
causes. Try to help out as much as I can. Greed is linked to competition and fear, both of which I lack. If you passion is in coding
and you do a good job at it, as is with everybody who is passionate about something, you do not have to be afraid of competition.
You create something, something beautiful and you will be awarded for it. Every time. Now please donate 5 euro on my PayPal account.

Sloth

The modern view of sloth is the failure of utilizing one’s talent and gifts. As I do not consider my coding as a gift, members of my family and
friends all perceive is that way. What I do perceive it to be, is that it is my passion. And I am doing it even while sleeping. So excess is maybe a better
sin for me. Luckily it does not exist. ๐Ÿ˜‰

Wrath

Anger or rage. This is a difficult one. Not that I become enraged but when people ask my help and I offer it to them freely and without any return value I expect them
to follow the advice I gave them. If they do not follow it, I think it is a pity but it’s like that. Yet if they come for that same advice again or start blaming other external factors instead of themselves in failing to comply with the advice,
I feel it as a waste of mine and their time and thus a certain disrespect. That is when I feel a bit of anger. I also feel a bit of anger when I am counting on somebody, something and it fails me. Yet
the anger is not towards the person, thing who failed me but towards myself for putting my trust in it. So I am guilty on this one. But only in a mild version ๐Ÿ™‚ And if you do not believe me you can test me, but don’t
try it while I am holding a Chainsaw.

Envy

I also have a bit of envy, but it is a healthy portion. When I see someone having the thing I want, I might want it too. I will talk to that person, if possible, congratulate him/her and ask him/her how they
did it. Then I will plan to acquire it also. The moment I envy something I go for it, otherwise I really do not envy it and I am not guilty. The mantra I follow is, if you can see it in your mind, you can hold it in your hands.
At the moment I envy authors of best seller books. But I am working on that. ๐Ÿ˜‰

Pride

Definitely guilty on that one. But I have to disagree with the definition of pride where it is linked to competition. I see pride as a healthy love for yourself and you wanting the best for yourself. You can have, be and do anything
you set your mind to. And you should love yourself enough to achieve it with respect and love for others. Take ownership of your faults but take even more ownership in your accomplishments as the world and soon yourself will forget all
the mistakes you made in favor of the good you do. Also please as an absolute minimum in self respect: brush your teeth, wash your armpits and clip your nails. ๐Ÿ™‚

I think that’s about it.

Some other facts about me:

1) I live with my wonderful girl Chanie who I met on a boat party called Cruises to pleasure.
2) We have two cats, Google (sphinx) and Nero (Siamese). And a fourth member of our family will soon arive: Moody a Peruvian hairless dog
3) When I was 17 I could hold my breath for 3 minutes 30 seconds. Today it is only half of that.
4) The first real coding I did was a hack for the two great giana sisters on my Amiga 500, followed by a hack on Lemmings. I was around 13.
5) Yes I wear non formal clothing outside work
6) I am attending http://www.phpconference.co.uk
7) I cannot wiggle my right foot clockwise and write a big six in the air without twitching that same foot!

My time to tag 7 people: Mathieu Laurent, Mathieu Kooiman, Christophe Geschรฉ, Zeev Suraski, Jensen Hunter, Langerak Berry, Ruud Alberts

Now it is your turn, happy tagging,
Nick Belhomme
Ps. want to see who tagged who in the PHP Community? WhoTaggedWho

Using Zend_Form, Zend_Config_Ini And Zend_Db_Table

Ok I am going to write a little bit about Zend_Form.
Yes I know a lot of small tutorials already exist but this one can
show you another trick ๐Ÿ™‚

My prefered way of using Zend_Form is to use it with a config.ini file.
It gives you a nice overview of special settings in a structured way. I love that.

One thing the manual does not explain is how to use it in addition with for instance dynamic population/value setting of a Zend_Form_Element object.

Say you have a select field that needs population. You cannot do that manually in the config file every time the database gets updated. There should be a better way. And actually there is.

Small example stripped to the bare minimum follows:

formConfig.ini

 [time]

time.action = "/time/save"
time.method = "post"
time.accept-charset = "utf-8"

time.elements.deliverytime_id.type = "select"
time.elements.deliverytime_id.options.label = "Delivery Time: "

time.elements.createsubmit.type = "submit"
time.elements.createsubmit.options.label = "create new"

Above we have a regular config.ini file ready to be parsed with Zend_Config_Ini.
For more information on how to use this with Zend_Form see Using a Zend_Config object

Time.php

<?php
class Time extends Zend_Db_Table {
    protected $_name = 'time';
}

Time.php is the Model for our time Table. This way we can easily do table manipulation without writing
any sql. This for potential portability to another database and your convencience.

TimeController.php

<?php
class TimeController extends Zend_Controller_Action {
    protected $time;
    protected $formTime;
    
    public function indexAction() {
        $this->view->formTime = $this->formTime;
    }
    
    public function init() {
        $this->time = new Time();
        $formConfig = new Zend_Config_Ini(APP_CONFIG.'/formCms.ini', 'time');
        $this->formTime = new Zend_Form($formConfig->time);
        $this->setupDeliveryTimesInFormSelect();
    }
    
    private function setupDeliveryTimesInFormSelect() {
        $select = $this->formTime->getElement('deliverytime_id');
    
        $deliveryTimes = $this->Time->fetchAll()->toArray();
        foreach($deliveryTimes as $timeOption) {
            $select->addMultiOption($timeOption['id'], $timeOption['time']);
        }
    }
}

This is a regular Controller. This is just stripped example code just to make you understand everything with more clarity. The key is in setupDeliveryTimesInFormSelect(). Here we get the form element from our $this->formTime.ย  It was already generated in the init() function.
Because all things are static in the config file we are going to populate it with options using the addMultiOption(). The values that are being used in the foreach loop are returned by a Zend_Db_Table object generated in Time.php.

The result of this code if you render your index view is a form with a submit button and a select box with options/values pairs set straight from a database. Because it is a select,ย  the submitted values are compared to the values in the form. Other form element types like text etc should have their submitted values validated and or filtered. You can find plenty of examples on how to set those options in the config.ini file on the net.

Happy Coding

Nick Belhomme
Your PHP5 Zend Certified Engineer