Posts Tagged ‘silverlight’

SEO for Silverlight

Tuesday, June 24th, 2008

I’ve got a problem.  A problem with Outlook and Exchange.  You see I have two exchange accounts on two different servers.  This is problem that I thought was rare at first, information pills
but I’m finding more and more that folks who work in the consulting space are having this challenge when their clients are using MS Exchange. 

On my mac, tadalafil
this isn’t really a big problem because I Entourage actually supports multiple Exchange servers.

On the PC side though, Outlook wants nothing to do with my multiple Exchange servers accounts.

To set up support for two accounts I had to go in to the control panel and locate the mail icon.

image

Then from there users have to figure out the very abstract user interface of what to do next.

image

Nope not “E-mail Accounts”  I need to create a new Profile.

image

I’ve already created a new profile, but this is where you’d click Add.

Give it a name that explains the account to you

image

Then you have to fill out this for and will try to auto configure your account

image

These seems to work most of the time.

So now you have two profiles.  Here’s where it gets annoying.  These profiles have no awareness of each other.  So if you get a meeting request in one and accept it, it will only be visible in that accounts calendar.

Then when you switch profiles you have no way to take that information with you.

Here’s where I’m using Google Calendar Sync.

It’s not perfect, but it does help.

image 

Once set up it will sync my Google calendar with my Outlook calendar.  Then when I switch profiles from one Outlook session to the next.  Google’s Calendar Sync stays active.  It will then begin syncing the information from my current profile.  

Of course the big issue here is that I have to continue switching my outlook profiles back and forth during the day to make sure all the information is up to date.  It’s still possible to receive a meeting request for the same time in both accounts.  Accept in one switch profiles.  Then accept in the other before Google get’s the calendars synced and I can create a conflict.

What Exchange really need to do is offer this a service feed directly from the server so that I don’t have to go through Outlook to activate all.

Phew!  That’s a lot of work just to make sure I don’t double book myself.

Of course this all gets much worse once you start to open yourself to other scheduling services like evite and upcoming.

Sometimes I have to remind myself that computers are supposed to make life easier not harder.

I’ve got a problem.  A problem with Outlook and Exchange.  You see I have two exchange accounts on two different servers.  This is problem that I thought was rare at first, information pills
but I’m finding more and more that folks who work in the consulting space are having this challenge when their clients are using MS Exchange. 

On my mac, tadalafil
this isn’t really a big problem because I Entourage actually supports multiple Exchange servers.

On the PC side though, Outlook wants nothing to do with my multiple Exchange servers accounts.

To set up support for two accounts I had to go in to the control panel and locate the mail icon.

image

Then from there users have to figure out the very abstract user interface of what to do next.

image

Nope not “E-mail Accounts”  I need to create a new Profile.

image

I’ve already created a new profile, but this is where you’d click Add.

Give it a name that explains the account to you

image

Then you have to fill out this for and will try to auto configure your account

image

These seems to work most of the time.

So now you have two profiles.  Here’s where it gets annoying.  These profiles have no awareness of each other.  So if you get a meeting request in one and accept it, it will only be visible in that accounts calendar.

Then when you switch profiles you have no way to take that information with you.

Here’s where I’m using Google Calendar Sync.

It’s not perfect, but it does help.

image 

Once set up it will sync my Google calendar with my Outlook calendar.  Then when I switch profiles from one Outlook session to the next.  Google’s Calendar Sync stays active.  It will then begin syncing the information from my current profile.  

Of course the big issue here is that I have to continue switching my outlook profiles back and forth during the day to make sure all the information is up to date.  It’s still possible to receive a meeting request for the same time in both accounts.  Accept in one switch profiles.  Then accept in the other before Google get’s the calendars synced and I can create a conflict.

What Exchange really need to do is offer this a service feed directly from the server so that I don’t have to go through Outlook to activate all.

Phew!  That’s a lot of work just to make sure I don’t double book myself.

Of course this all gets much worse once you start to open yourself to other scheduling services like evite and upcoming.

Sometimes I have to remind myself that computers are supposed to make life easier not harder.

I’ve got a problem.  A problem with Outlook and Exchange.  You see I have two exchange accounts on two different servers.  This is problem that I thought was rare at first, information pills
but I’m finding more and more that folks who work in the consulting space are having this challenge when their clients are using MS Exchange. 

On my mac, tadalafil
this isn’t really a big problem because I Entourage actually supports multiple Exchange servers.

On the PC side though, Outlook wants nothing to do with my multiple Exchange servers accounts.

To set up support for two accounts I had to go in to the control panel and locate the mail icon.

image

Then from there users have to figure out the very abstract user interface of what to do next.

image

Nope not “E-mail Accounts”  I need to create a new Profile.

image

I’ve already created a new profile, but this is where you’d click Add.

Give it a name that explains the account to you

image

Then you have to fill out this for and will try to auto configure your account

image

These seems to work most of the time.

So now you have two profiles.  Here’s where it gets annoying.  These profiles have no awareness of each other.  So if you get a meeting request in one and accept it, it will only be visible in that accounts calendar.

Then when you switch profiles you have no way to take that information with you.

Here’s where I’m using Google Calendar Sync.

It’s not perfect, but it does help.

image 

Once set up it will sync my Google calendar with my Outlook calendar.  Then when I switch profiles from one Outlook session to the next.  Google’s Calendar Sync stays active.  It will then begin syncing the information from my current profile.  

Of course the big issue here is that I have to continue switching my outlook profiles back and forth during the day to make sure all the information is up to date.  It’s still possible to receive a meeting request for the same time in both accounts.  Accept in one switch profiles.  Then accept in the other before Google get’s the calendars synced and I can create a conflict.

What Exchange really need to do is offer this a service feed directly from the server so that I don’t have to go through Outlook to activate all.

Phew!  That’s a lot of work just to make sure I don’t double book myself.

Of course this all gets much worse once you start to open yourself to other scheduling services like evite and upcoming.

Sometimes I have to remind myself that computers are supposed to make life easier not harder.

I’ve got a problem.  A problem with Outlook and Exchange.  You see I have two exchange accounts on two different servers.  This is problem that I thought was rare at first, information pills
but I’m finding more and more that folks who work in the consulting space are having this challenge when their clients are using MS Exchange. 

On my mac, tadalafil
this isn’t really a big problem because I Entourage actually supports multiple Exchange servers.

On the PC side though, Outlook wants nothing to do with my multiple Exchange servers accounts.

To set up support for two accounts I had to go in to the control panel and locate the mail icon.

image

Then from there users have to figure out the very abstract user interface of what to do next.

image

Nope not “E-mail Accounts”  I need to create a new Profile.

image

I’ve already created a new profile, but this is where you’d click Add.

Give it a name that explains the account to you

image

Then you have to fill out this for and will try to auto configure your account

image

These seems to work most of the time.

So now you have two profiles.  Here’s where it gets annoying.  These profiles have no awareness of each other.  So if you get a meeting request in one and accept it, it will only be visible in that accounts calendar.

Then when you switch profiles you have no way to take that information with you.

Here’s where I’m using Google Calendar Sync.

It’s not perfect, but it does help.

image 

Once set up it will sync my Google calendar with my Outlook calendar.  Then when I switch profiles from one Outlook session to the next.  Google’s Calendar Sync stays active.  It will then begin syncing the information from my current profile.  

Of course the big issue here is that I have to continue switching my outlook profiles back and forth during the day to make sure all the information is up to date.  It’s still possible to receive a meeting request for the same time in both accounts.  Accept in one switch profiles.  Then accept in the other before Google get’s the calendars synced and I can create a conflict.

What Exchange really need to do is offer this a service feed directly from the server so that I don’t have to go through Outlook to activate all.

Phew!  That’s a lot of work just to make sure I don’t double book myself.

Of course this all gets much worse once you start to open yourself to other scheduling services like evite and upcoming.

Sometimes I have to remind myself that computers are supposed to make life easier not harder.

There are more challenges when it comes to optimizing for search engines to consume your content if it is a dynamic Rich UI application that doesn’t rely on Ajax. While Google is able to pick up Flash SWF files during its crawl, gynecologist
this does not guarantee that the content is parsed correctly or given the same weight as any other file formats or a pure HTML/AJAX page. Worse, disorder
if the application uses a web service, page
how can it be guaranteed that all the pages are crawled and returned correctly?

In most cases you will need to make sure that the page hosting the application has some html text that describes the application and what it offers. So in essence treat the page in the same way you would HTML.

When possible expose the content of the application so that it too can be indexed.

Simple Silverlight application – XAML to XHTML with XSLT

For a Silverlight element that contains all of its content in the XAML the best method would be to transforms the XAML using XSLT into friendly XHTML. The goal is to contain the translated XAML into a <div> element that would be replaced by the Silverlight control. Search engines would find the XHTML while browsers with Silverlight installed would see the Silverlight app.

 

   1: <div id="SLHost">
   2:     <asp:Xml ID="XHTML" runat="server" DocumentSource="seo.xaml"
   3:   TransformSource="XAML2XHTML.xslt" EnableViewState="False"/>
   4:     <script type="text/JavaScript">
   5:         createSilverlight();
   6:     </script>
   7: </div>

Then use the following XAML2XHTML.xslt

   1: <?xml version="1.0" encoding="utf-8"?>
   2:  
   3: <xsl:stylesheet version="1.0"
   4:     xmlns:sl="http://schemas.microsoft.com/client/2007"
   5:     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   6:     exclude-result-prefixes="sl">
   7:  
   8:   <xsl:output omit-xml-declaration="yes" indent="yes"/>
   9:  
  10:   <xsl:template match="/">
  11:     <xsl:comment>This is the text that is in the Silverlight XAML:</xsl:comment>
  12:     <xsl:apply-templates select="*"/>
  13:   </xsl:template>
  14:  
  15:   <xsl:template match="sl:Canvas">
  16:     <div>
  17:       <xsl:apply-templates select="*"/>
  18:     </div>
  19:   </xsl:template>
  20:  
  21:   <xsl:template match="node()"/>
  22:  
  23:   <xsl:template match="sl:Image">
  24:     <div>
  25:       <img src="{@Source}"/>
  26:     </div>
  27:   </xsl:template>
  28:   <xsl:template match="sl:MediaElement">
  29:     <div class="Media">
  30:       <a href="{@Source}">Media</a>
  31:     </div>
  32:   </xsl:template>
  33:  
  34:   <xsl:template match="sl:TextBlock">
  35:     <div>
  36:       <xsl:value-of select="@Text"/>
  37:       <xsl:value-of select="text()"/>
  38:       <xsl:apply-templates select="*"/>
  39:     </div>
  40:   </xsl:template>
  41:   <xsl:template match="sl:LineBreak">
  42:     <br/>
  43:   </xsl:template>
  44:  
  45:   <xsl:template match="sl:Run">
  46:     <span>
  47:       <xsl:value-of select="@Text"/>
  48:       <xsl:value-of select="text()"/>
  49:     </span>
  50:   </xsl:template>
  51: </xsl:stylesheet>

 

Handling more advanced Silverlight applications

How do you design an application that could have dynamic content and robust interaction while at the same time enable a web crawler to understand and categorize the underlying content correctly? Unfortunately there is no simple answer or single correct answer. It depends highly on the application’s purpose. In some situations there will be no way to offer the content of the application up to spider outside of the application. In this case it’s best to have as much meta information on the page hosting the application as possible. By following the standard HTML methods in this document you can still extend the indexability of your application by making sure external links are properly formatted and that high ranking sites link to your application.

Detect and Serve

It requires a little more work up front from a development standpoint to go this route, but if you really have a strong need to get the content in your application indexed then this will be the best approach. The goal is to develop the code of the site to be delivered in multiple formats based on the user agent that is accessing the content. This isn’t all that uncommon anyway with the large range of browser and devices out there that are consuming the web already. Most applications are built with the data stored separately from the interaction in a database or local XML document. The site would have to be built so that it can serve up HTML pages for those who don’t have Flex/Flash/Silverlight installed. Plus, we could potentially change these pages for mobile devices like the iPhone that don’t yet support Flash or Silverlight.

It’s also recommend to have some enticement or value proposition to explain to real users why it would be beneficial to add the plug-ins required to get the optimal experience.

The goal would be to have clients that have the plug-in or runtime installed, would be provided the rich interaction. On those that don’t, a functional page in HTML will be provided. More importantly, to the search engines, these pages that are generated will be tagged and indexed correctly, making the content of our applications visible and increase their visibility.

Up to date books from O’Reilly

Wednesday, May 21st, 2008

2512159922_f5fa552a18 I picked up the Essential Silverlight 2.0 book while I was at the Web 2.0 Expo.  I’ve been meaning to share.  It’s the first time I’ve purchased an “Up To Date” book from O’Reilly.  I’m waiting form my first update to come in the mail.

To update your book you have the  option to print out the pages or view them online for free, adiposity but I like the idea of updating the book itself. 

To put in the new pages all you have to do is pop the little metal posts out from the plastic cover then add in the pages.

The idea behind O’Reilly’s “Up To Date” books

For publishers of printed technology books, stuff it’s always been challenging to get a book written, edited, printed, and delivered while the content of the book is still relevant and needed by the audience. Some of our readers are happy to have the information they need delivered quickly in electronic form, but we hear from others that they still prefer the actual printed page. The Up-to-Date format is our answer to the need to deliver information on new technologies quickly, yet in printed form. And the beauty of it is that the book can take shape right along with the software, providing coverage of the CTPs, betas, and RTM releases as they become available.

Because the cover is plastic I have noticed a small issue in that the printing seems to flake off from the cover.  Hopefully they find a way to fix this in future version.  Of course I’d be super happy if they had a version that would work on my Sony Reader too.

Oh, and the book is very good too, but that’s another post!

Expression 2 is out

Friday, May 2nd, 2008

image

Microsoft released the Expression 2.0  suite of products today.  I’ve been using expression since last year and religiously updating whenever a new beta or preview version of any of the applications as they were released.  At first I wasn’t a big fan of the tools, therapist but over time I’ve really come to enjoy them and they have become my default tools to use for web and Silverlight development.  Combined with Visual Studio 2008 it all becomes a powerful environment.   Now that I’m learning how to develop and design in WPF I’m using Blend all the time to put together my UI objects.

(more…)

Silverlight 2.0 Flickr WordPress Widget

Tuesday, April 8th, 2008

I had the challenge of creating both a simple Silverlight 2.0 flickr viewer and a WordPress widget that used silverlight so I combined the two projects in to one.

The first part was creating the Silverlight 2.0 Flickr RSS viewer.

   1: <UserControl
   2:     xmlns="http://schemas.microsoft.com/client/2007"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     x:Class="FlickrShow.Page"
   5:     Width="auto" 
   6:     Height="auto" 
   7:     x:Name="FlickrShow" 
   8:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
   9:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   
  10:     mc:Ignorable="d">
  11:  
  12:     <Grid x:Name="LayoutRoot" Background="#FF424242" >
  13:         <Image HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="ImageItem" VerticalAlignment="Stretch" Stretch="Uniform" Cursor="Hand" Source="OpeningImage.jpg">
  14:             <Image.Resources>
  15:                 <Storyboard x:Name="FadeOutAnimation">
  16:                     <DoubleAnimation Duration="00:00:00.20" From="1" To="0"                        
  17:                                      Storyboard.TargetProperty="Opacity"                        
  18:                                      Storyboard.TargetName="BigImage" />
  19:                 </Storyboard>
  20:                 <Storyboard x:Name="FadeInAnimation">
  21:                     <DoubleAnimation Duration="00:00:00.20" From="0" To="1"                        
  22:                                      Storyboard.TargetProperty="Opacity"                        
  23:                                      Storyboard.TargetName="BigImage" />
  24:                 </Storyboard>
  25:             </Image.Resources>
  26:         </Image>
  27:         <TextBox Height="30" VerticalAlignment="Bottom" Text="" x:Name="LabelBox" Background="#2B000000" Foreground="#FFFFFFFF" BorderThickness="0,0,0,0" FontSize="11" />
  28:     </Grid>
  29: </UserControl>

page.xaml

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Windows;
   5: using System.Windows.Controls;
   6: using System.Windows.Documents;
   7: using System.Windows.Input;
   8: using System.Windows.Media;
   9: using System.Windows.Media.Animation;
  10: using System.Windows.Shapes;
  11: using System.Windows.Threading;
  12: using System.Windows.Browser;
  13: using System.Xml.Linq;
  14: using System.Windows.Media.Imaging;
  15: using System.Windows.Resources;
  16: using System.IO;
  17: using System.Net;
  18: using System.Xml;
  19: using System.ServiceModel.Syndication;
  20:  
  21:  
  22:  
  23: namespace FlickrShow
  24: {
  25:     public class SettingDefinition
  26:     {
  27:         public string userID { get; set; }
  28:         public string feedType  { get; set; }
  29:         public string tags  { get; set; }
  30:         public string duration { get; set; }
  31:     }
  32:  
  33:     public partial class Page : UserControl
  34:     {
  35:         string currentUserID;
  36:         string currentFeedType;
  37:         string currentTags;
  38:         int currentDuration;
  39:  
  40:         DateTime lastUpdate;
  41:         string currentLink;
  42:         String[,] imgArray = new String[20, 3]; //Array to store information pulled from the RSS
  43:         int i = 0;  //handy little index number to count with
  44:         int imageIndex = 0;  //another index used for displaying specific images
  45:         DispatcherTimer dt = new DispatcherTimer();
  46:         
  47:         public Page(string UserID, string FeedType, string Tags, int Duration)
  48:         {
  49:             InitializeComponent();
  50:  
  51:             currentUserID = UserID;
  52:             currentFeedType = GetFeedType(FeedType);
  53:             currentTags = Tags;
  54:             currentDuration = Duration;
  55:  
  56:             this.Loaded += new RoutedEventHandler(Page_Loaded);
  57:             HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri("http://api.flickr.com/services/feeds/" + currentFeedType + currentUserID + currentTags + "&format=rss2"));
  58:  
  59:             request.BeginGetResponse(new AsyncCallback(getImages), request);
  60:  
  61:             lastUpdate = DateTime.Now;
  62:  
  63:             dt.Interval = new TimeSpan(0, 0, 0, currentDuration);
  64:             dt.Tick += new EventHandler(dt_Tick);
  65:             dt.Start();
  66:  
  67:         }
  68:  
  69:         void getImages(IAsyncResult asyncResult)
  70:         {
  71:             XNamespace mediaNamespace = "http://search.yahoo.com/mrss/";
  72:  
  73:  
  74:             HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
  75:             HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
  76:  
  77:             XmlReader reader = XmlReader.Create(response.GetResponseStream());
  78:             SyndicationFeed feed = SyndicationFeed.Load(reader);
  79:  
  80:             foreach (SyndicationItem item in feed.Items)
  81:             {
  82:                 //let's put the results in a multidimesional Array, because they are fun 
  83:                 imgArray.SetValue(item.ElementExtensions[1].GetReader().GetAttribute("url"), i, 0);
  84:                 imgArray.SetValue(item.Title.Text, i, 1);
  85:                 imgArray.SetValue("http://www.flickr.com" + item.Links[0].Uri.AbsolutePath, i, 2);
  86:                 i++;
  87:             }
  88:         }
  89:  
  90:         void Page_Loaded(object sender, RoutedEventArgs e)
  91:         {
  92:                       
  93:             ImageItem.MouseEnter += new MouseEventHandler(ImageItem_MouseEnter);
  94:             ImageItem.MouseLeave += new MouseEventHandler(ImageItem_MouseLeave);
  95:             ImageItem.MouseLeftButtonDown += new MouseButtonEventHandler(ImageItem_MouseButtonDown);
  96:  
  97:             
  98:         }
  99:  
 100:  
 101:  
 102:         void dt_Tick(object sender, EventArgs e)
 103:         {
 104:             //this is our timer control, every time we update this will run
 105:             Update();   
 106:         }
 107:  
 108:         void Update()
 109:         {
 110:             //Updating the time
 111:             DateTime now = DateTime.Now;
 112:             TimeSpan elapsed = now - lastUpdate;
 113:             lastUpdate = now;
 114:             //do your loop processing here
 115:             ChangeImage();
 116:             
 117:         }
 118:  
 119:         void ChangeImage()
 120:         {
 121:             //This is where we actually update the <image> XAML. 
 122:  
 123:             if (imageIndex <= (i - 1))
 124:             {
 125:                 LabelBox.Text = imgArray.GetValue(imageIndex, 1) as string;
 126:                 ImageItem.SetValue(Image.SourceProperty, imgArray.GetValue(imageIndex, 0) as string);
 127:                 currentLink = imgArray.GetValue(imageIndex, 2) as string;
 128:                 imageIndex++;
 129:             }
 130:             else
 131:             {
 132:                 imageIndex = 0;
 133:                 LabelBox.Text = imgArray.GetValue(imageIndex, 1) as string;
 134:                 ImageItem.SetValue(Image.SourceProperty, imgArray.GetValue(imageIndex, 0) as string);
 135:                 currentLink = imgArray.GetValue(imageIndex, 2) as string;
 136:                 imageIndex++;
 137:             }
 138:  
 139:         }
 140:  
 141:         public string GetFeedType(string feedSetting)
 142:         {
 143:             switch (feedSetting)
 144:                 {
 145:                 case "Public":
 146:                         return "photos_public.gne?id=";                        
 147:                 case "Friends":
 148:                     //This is for a future release
 149:                         return "photos_friends.gne?user_id=";
 150:                 default:
 151:                         return "photos_public.gne?id="; 
 152:                 }
 153:             
 154:         }
 155:  
 156:         public string FormatTags(string tagsElement)
 157:         {
 158:             if (tagsElement.Length > 0)
 159:             {
 160:                 return "&tags=" + tagsElement;
 161:             }
 162:             else { return ""; }
 163:         }
 164:  
 165:         private void ImageItem_MouseEnter(object sender, MouseEventArgs e)
 166:         {            
 167:                 dt.Stop();
 168:         }
 169:  
 170:         private void ImageItem_MouseLeave(object sender, MouseEventArgs e)
 171:         {
 172:             dt.Start();
 173:         }
 174:  
 175:         private void ImageItem_MouseButtonDown(object sender, MouseButtonEventArgs e)
 176:         {
 177:             HtmlPage.Window.Navigate(new Uri(currentLink, UriKind.Absolute), "_flickr");
 178:         }
 179:     }
 180: }

page.xaml.cs

   1: using System.Windows;
   2: using System;
   3:  
   4: namespace FlickrShow
   5: {
   6:     public partial class App : Application 
   7:     {
   8:  
   9:         public App() 
  10:         {
  11:             this.Startup += this.OnStartup;
  12:             this.Exit += this.OnExit;
  13:  
  14:             InitializeComponent();
  15:         }
  16:  
  17:         private void OnStartup(object sender, StartupEventArgs e) 
  18:         {
  19:             // Load the main control here
  20:             string currentUserID = e.InitParams["flickr_userID"];
  21:             string currentFeedType = "Public";
  22:             string currentTags = "";
  23:             int currentDuration = Convert.ToInt32(e.InitParams["time"]);
  24:  
  25:             this.RootVisual = new Page(currentUserID, currentFeedType, currentTags, currentDuration);
  26:         }
  27:  
  28:         private void OnExit(object sender, EventArgs e) 
  29:         {
  30:  
  31:         }
  32:     }
  33: }

App.xaml.cs

   1: <?php
   2: /*
   3: Plugin Name: Silverlight Flickr Widget
   4: Plugin URI: http://www.futile.com/
   5: Description: A widget which will display your latest Flickr photos using Silverlight.
   6: Author: Ryan T. Lane
   7: Version: 0.2
   8: Author URI: http://futile.com/
   9: 
  10: Installing
  11: 1. Make sure you have the Widget plugin available at http://automattic.com/code/widgets/
  12: 1. Copy wordpressWidgetSilverlightFlickr.php to your plugins folder, /wp-content/plugins/widgets/
  13: 2. Activate it through the plugin management screen.
  14: 3. Go to Themes->Sidebar Widgets and drag and drop the widget to wherever you want to show it.
  15: 
  16: Changelog
  17: 0.2 = First public release.
  18: */
  19:  
  20:  
  21: function WidgetFlickrSilverlight($args) {
  22:     extract($args);
  23:     
  24:     $options = get_option('WidgetFlickrSilverlight');
  25:     if( $options == false ) {
  26:         $options[ 'flickr_userID' ] = '21854617@N00';
  27:         $options[ 'time' ] = 4;
  28:     }
  29:     
  30:     $time = $options[ 'time' ];
  31:     $flickr_userID = $options[ 'flickr_userID' ];
  32:     
  33:     echo $before_widget;
  34:     
  35:     echo $before_title . 'Flickr' . $after_title; 
  36:     ?>
  37:                <script type="text/javascript">
  38:                     function onSilverlightError(sender, args) {
  39:                     if (args.errorType == "InitializeError")  {
  40:                         var errorDiv = document.getElementById("errorLocation");
  41:                         if (errorDiv != null)
  42:                         errorDiv.innerHTML = args.errorType + "- " + args.errorMessage;
  43:                         }
  44:                     }
  45:                 </script>
  46:                 
  47:                 <!-- Runtime errors from Silverlight will be displayed here.
  48:                     This will contain debugging information and should be removed or hidden when debugging is completed -->
  49:                 <div id='errorLocation' style="font-size: small;color: Gray;"></div>
  50:  
  51:                 <div id="silverlightControlHost">
  52:                     <object data="data:application/x-silverlight," type="application/x-silverlight-2-b1" width="100%" height="100%">
  53:                         <param name="source" value="/wp-content/plugins/widgets/FlickrShow.xap"/>
  54:                         <param name="onerror" value="onSilverlightError" />
  55:                         <param name="background" value="white" />
  56:                         <param name="initParams" value="time=<?php echo $time; ?>,flickr_userID=<?php echo $flickr_userID; ?>" />
  57:                         
  58:                         <a href="http://go.microsoft.com/fwlink/?LinkID=108182" style="text-decoration: none;">
  59:                              <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
  60:                         </a>
  61:                     </object>
  62:                     <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>
  63:                 </div>   
  64:         <?php echo $after_widget; ?>
  65: <?php
  66: }
  67:  
  68: function WidgetFlickrSilverlight_control() {
  69:     $options = $newoptions = get_option('WidgetFlickrSilverlight');
  70:     if( $options == false ) {
  71:         $newoptions[ 'title' ] = 'Flickr Photos';
  72:     }
  73:     if ( $_POST["flickr-submit"] ) {
  74:         $newoptions['title'] = strip_tags(stripslashes($_POST["flickr-title"]));
  75:         $newoptions['time'] = strip_tags(stripslashes($_POST["time"]));
  76:         $newoptions['flickr_userID'] = strip_tags(stripslashes($_POST["flickr-userID"]));
  77:     }
  78:     if ( $options != $newoptions ) {
  79:         $options = $newoptions;
  80:         update_option('WidgetFlickrSilverlight', $options);
  81:     }
  82:     $title = wp_specialchars($options['title']);
  83:     $time = wp_specialchars($options['time']);
  84:     if ( empty($items) || $items < 1 ) $items = 3;
  85:     $flickr_userID = wp_specialchars($options['flickr_userID']);
  86:  
  87: ?>
  88:     <p><label for="flickr-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="flickr-title" name="flickr-title" type="text" value="<?php echo $title; ?>" /></label></p>
  89:     <p><label for="flickr-userID"><?php _e('Flickr User ID:'); ?> <input style="width: 250px;" id="flickr-title" name="flickr-userID" type="text" value="<?php echo $flickr_userID; ?>" /></label></p>
  90:     <p style="text-align:center; line-height: 30px;"><?php _e('Time per image in seconds:'); ?> <select id="time" name="time"><?php for ( $i = 1; $i <= 10; ++$i ) echo "<option value='$i' ".($time==$i ? "selected='selected'" : '').">$i</option>"; ?></select></p>
  91:     <p align='left'>
  92:     * Your user ID can be found on your Flickr RSS page. Scroll down to the bottom of the page until you see the <em>Feed</em> link and copy the value after id from the URL into the box above.<br />
  93:     <br clear='all'></p>
  94:     <input type="hidden" id="flickr-submit" name="flickr-submit" value="1" />
  95: <?php
  96: }
  97:  
  98:     function WidgetFlickrSilverlight_init() {
  99:         register_widget_control('Silverlight Flickr', 'WidgetFlickrSilverlight_control', 500, 250);
 100:         register_sidebar_widget('Silverlight Flickr', 'WidgetFlickrSilverlight');
 101:     }
 102:     add_action( "init", "WidgetFlickrSilverlight_init" );
 103:  
 104: ?>

wordpressWidgetSilverlightFlickr.php

 

The php page and compiled .xap files are placed in the /wp-content/plugins/widgets/ folder.

First you will have to activate the plug-in.

image

Then enable the widget in one of your sidebars and edit the properties to include your information.

image

if you don’t know your flickr user id you can get it from idGettr

That’s all for now.  I will do a more detailed write up of what is going on up above very soon.

You can grab the source from CodePlex.

Happy Valentine’s Day

Thursday, February 14th, 2008

Silverlight Valentine

I worked on a little Silverlight Valentine’s day e-card for Microsoft. The original card design was going to be a bit more, pills but we had some time constraints to deal with. Overall, tadalafil it’s a simple application. The meat of the developement work was done by the talented folks at Aeshen.

I would like to go back and really rework the concept more, but you know, I like to make code and design perfect and the real world demands that stuff ships on time. Enjoy. I hope everyone has a wonderful Valentine’s day.

xoxo
Ryan

Mix 2008

Thursday, February 7th, 2008

Forward Track

ForwardTrack is a new system created by Eyebeam R&D (redeveloped with the assist from Stamen Design) designed to promote on-line activism. The system tracks and maps the diffusion of email forwards, prosthetic political calls-to-action, order and online petitions. It can trace email forwards, ed map the impact of blogs, and facilitate web-based sign-ups and social networking. Our goal is to help people understand decentralized networks and see the power of “6 degrees of separation.” ForwardTrack technology helps prove that one person can make a difference.

I’m downloading and installing now. I’ll see if I can get something up and running soon to test. As you can see I’m rather excited about this.

Forward Track

ForwardTrack is a new system created by Eyebeam R&D (redeveloped with the assist from Stamen Design) designed to promote on-line activism. The system tracks and maps the diffusion of email forwards, prosthetic political calls-to-action, order and online petitions. It can trace email forwards, ed map the impact of blogs, and facilitate web-based sign-ups and social networking. Our goal is to help people understand decentralized networks and see the power of “6 degrees of separation.” ForwardTrack technology helps prove that one person can make a difference.

I’m downloading and installing now. I’ll see if I can get something up and running soon to test. As you can see I’m rather excited about this.

Forward Track

ForwardTrack is a new system created by Eyebeam R&D (redeveloped with the assist from Stamen Design) designed to promote on-line activism. The system tracks and maps the diffusion of email forwards, prosthetic political calls-to-action, order and online petitions. It can trace email forwards, ed map the impact of blogs, and facilitate web-based sign-ups and social networking. Our goal is to help people understand decentralized networks and see the power of “6 degrees of separation.” ForwardTrack technology helps prove that one person can make a difference.

I’m downloading and installing now. I’ll see if I can get something up and running soon to test. As you can see I’m rather excited about this.

Mix 2008I’ll be on a panel at this year’s Mix event, tadalafil talking about workflow and process and such. It’s a pretty talented group of people and should make for a good time.

Making it Simple: Designer/Developer Workflow
Speakers: Marcelo Marer (Avenue A Razorfish), ambulance Ken Azuma (Second Factory), Robby Ingebretsen (Identity Mine), Ryan Lane (Wunderman), Mark Ligameri (frog design), Robert Tuttle (frog design)
Audience: Creative
Session Type: Panel
How do you combine a designer’s vision with the requirements of productive software? Left brain/Right brain workflow is a sophisticated problem that impacts us all but has no easy answers. Industry experts will share their learnings and invite you to join in on a lively discussion about the merits and costs of different approaches.

My first Chumby widget

Tuesday, November 27th, 2007

I recently got a Chumby and have been playing around with writing some widgets that I wanted. The first one is this Seattle Traffic Cam widget:


I built it using OpenLaszlo instead of Adobe Flash tools since I don’t own a remotely recent version of the Flash software and I wasn’t going to spend $700 on getting it. So I did a little research and found an OpenSource option. It’s a little wonky but it did the trick.

Now I just need to find a way to get the Silverlight player to work on the Chumby. I wonder if anyone is working on a Linux Arm build of the player?