Ahmad Masykur

Share your knowledge although one function!

About the author

Ahmad Masykur is a Software Architecture Engineer at PT. Freeport Indonesia Jakarta Indonesia.
In this blog, I share things of interest to me. Most topics are likely to be related to software development, but don't hold me to it.

Certificates



Awards


Powered by

Widget Prayer Time not found.

There is an error in XML document (4, 16278).X

Page List

Validators


Ahmad Masykur

How to Make Our Website to be Ready for IE8

Today, I have email from Microsoft TechNet Flash about "how to get ready for IE8". It is challenge for me to make my blog ready for IE8. My blog have already XHTML 1.0 Transitional and CSS 2.1 compliance, but still reported as not ready for IE8 (see picture below).

image

What happen with my blog? IE8 have difference standard with W3C? After following link from TechNet flash email, the problem is: my blog have not META tag to tell IE8 that the page is ready for IE8 view. After apply X-UA-Compatible META tag in my BlogEngine theme, my blog is now comply with IE8.

image

Here’s requirement to be ready for IE8.

  1. Make sure your HTML markup is comply to HTML 4, XHTML 1.0 or XHTML 1.1 defined in doctype of the page. You can validate your page with online markup validation tools at http://validator.w3.org/
  2. Make sure your CSS is use at least CSS level 2.1 compliance. You can validate your page with online CSS validation tools at http://jigsaw.w3.org/css-validator/
  3. Place the following HTML META tag into the top of the HEAD element of each Web page (before tags other than TITLE or META):
    <meta http-equiv="X-UA-Compatible" content="IE=8"/>
    This will tell Windows Internet Explorer 8 to render each page using CSS 2.1 standards.

After HTML, CSS and HTML META has been applied, the page will ready for IE8.

References:

http://msdn.microsoft.com/en-us/ie/cc405106.aspx
http://msdn.microsoft.com/id-id/library/cc817570(en-us).aspx
http://msdn.microsoft.com/id-id/library/dd433047(en-us,VS.85).aspx
http://msdn.microsoft.com/id-id/library/cc817572(en-us).aspx


Categories: Tips | IE
Permalink | Comments (3) | Post RSSRSS comment feed

Get Microsoft Certifications at 10% discount and free retake

top_banner
Staying Ahead in Your Career with Microsoft Certification

A challenging economic climate is driving many organizations to re-examine their operations. Ensuring employees have the skills to utilize the latest software capabilities helps companies fully realize the potential value of their technology investments while achieving reduced costs and improved staffing efficiencies.

As responsible IT professional, it is essential to stay current on the latest technologies and proactively upgrade one’s skills. This will help the team to provide the necessary expertise to improve the organization’s IT environment. Certification, which encompasses training and skills validation, is a proven way to maximize the effectiveness of IT professionals. Check out more information from TechRepublic on 10 reasons why certification will be important in 2009

How do you decide on the relevant Certification to invest in? Find out more on the demand of IT Skills and Certification available in the market. Some reports you can refer to include TechRepublic’s The industry's 10 best IT certifications, IT Skills@Work – An Asia Pacific Perspective by Kelly IT Resources (October 2008) and TechRepublic’s IT Salary Survey 2009.

This is the best time to join the
Microsoft Certified Professional community!
If you are interested in getting a Microsoft Certification, here’s the good news … go to www.learnANDcertify.com by April 30, 2009 and key in the Promo Code : ID4747BA to enjoy a 10% discount on your next Microsoft Certification exam. Even better, you will enjoy a free retake if you fail the exam. (Limited to Indonesia usage only)

Note : Once you decided on obtaining a Microsoft Certification, you can participate in the upcoming Live Meeting on “Getting Started with Microsoft Certification” on April 7, 2009 11:30pm Jakarta Time or April 8, 2009 9:30am Jakarta Time. Also you can visit www.learnANDcertify.com to find out more on the resources available.

Yours sincerely,
Ahmad Masykur
Microsoft ASP.NET MVP

Categories: Certification
Permalink | Comments (1) | Post RSSRSS comment feed

How To Create Silverlight Avatar for INDC blogs site

I have created Silverlight avatar for Community Server blog list page (http://geeks.netindonesia.net/blogs) a week ago as requested by Naren. I think its no difficult to replace HTML avatar with Silverlight avatar on the fly. Just query DOM using jQuery for existing avatar, grab photo Url information, hide it and replace with new Silverlight avatar. Here is step by step to create Silverlight avatar for CS theme on geeks site.

Create Silverlight project using Expression Blend.

I'm created two path to put avatar image and two StackPanel contain text-boxes for view counter text. Second path and StackPanel will mirrored-down to make shadow-mirror effect. These path will be binded by same image.

image

Here is the XAML for that design.

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="Avatar.Page"
    Width="133" Height="130">
    <Grid x:Name="LayoutRoot" Clip="M0,0 L133,0 L133,130 L0,130 z">
        <Grid.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF8FC2E4"/>
                <GradientStop Color="#FFFFFFFF" Offset="1"/>
            </LinearGradientBrush>
        </Grid.Background>
        <Grid>
            <Canvas Margin="48 1 1 10" >
                <Path Data="M0,0 L82,0 L82,102 L0,91 z" Stretch="Fill" Stroke="#CCFFFFFF" >
                    <Path.Fill>
                        <ImageBrush x:Name="Photo" />
                    </Path.Fill>
                </Path>
                <Path Canvas.Top="193.5" Data="M1.5,12 L81,0 L81.75,73.5 L0.25,82.5 z" Stretch="Fill" Stroke="#CCFFFFFF" RenderTransformOrigin="0,0" Height="102.188" Width="82.5" Canvas.Left="0.125" >
                    <Path.OpacityMask>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.4,0">
                            <GradientStop Color="#AAFFFFFF" Offset="1"/>
                            <GradientStop Color="#00FFFFFF" Offset="0"/>
                        </LinearGradientBrush>
                    </Path.OpacityMask>
                    <Path.Fill>
                        <ImageBrush x:Name="PhotoShadow" />
                    </Path.Fill>
                    <Path.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform ScaleY="-1"/>
                            <SkewTransform/>
                            <RotateTransform/>
                            <TranslateTransform X="0" Y="0"/>
                        </TransformGroup>
                    </Path.RenderTransform>
                </Path>
            </Canvas>
            <Canvas Margin="2,0,0,0">
                <Path Height="18" Width="134" Canvas.Left="-3" Canvas.Top="86.25" Data="M128,103.25 L-3,86.25" Fill="#FFFFFFFF" Stretch="Fill" Stroke="#B2FFFFFF"/>
                <StackPanel Canvas.Top="48" RenderTransformOrigin="0.5,0.5">
                    <StackPanel.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform/>
                            <SkewTransform AngleY="6.972"/>
                            <RotateTransform/>
                            <TranslateTransform Y="4.006"/>
                        </TransformGroup>
                    </StackPanel.RenderTransform>
                    <TextBlock x:Name="ViewCount" Text="9999" TextWrapping="Wrap" FontFamily="Arial" FontSize="20" Foreground="#FF023D9E" HorizontalAlignment="Right"/>
                    <TextBlock Text="Views" TextWrapping="Wrap" FontFamily="Arial" FontSize="16" Foreground="#FF023D9E" HorizontalAlignment="Right"/>
                </StackPanel>
                <StackPanel Canvas.Top="84" RenderTransformOrigin="0.5,0.5">
                    <StackPanel.OpacityMask>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="#00FFFFFF"/>
                            <GradientStop Color="#AAFFFFFF" Offset="1"/>
                        </LinearGradientBrush>
                    </StackPanel.OpacityMask>
                    <StackPanel.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform ScaleY="-1"/>
                            <SkewTransform AngleY="7.585"/>
                            <RotateTransform/>
                            <TranslateTransform Y="3.288"/>
                        </TransformGroup>
                    </StackPanel.RenderTransform>
                    <TextBlock x:Name="ViewCountShadow" Text="9999" TextWrapping="Wrap" FontFamily="Arial" FontSize="20" Foreground="#FF023D9E" HorizontalAlignment="Right"/>
                    <TextBlock Text="Views" TextWrapping="Wrap" FontFamily="Arial" FontSize="16" Foreground="#FF023D9E" HorizontalAlignment="Right"/>
                </StackPanel>
            </Canvas>
        </Grid>
    </Grid>
</UserControl>

Write code-behind to bind avatar image and view counter.

This code-behind used to bind avatar image and view counter. The image url and view counter passed by InitParams property from javascript. The App.xaml.cs code-behind used to get InitParams and Page.xaml.cs used to bind the image and text from parameter values.

App.xaml.cs

 1 using System.Windows;
 2 using System;
 3 using System.Windows.Browser;
 4 
 5 namespace Avatar
 6 {
 7     public partial class App : Application 
 8     {
 9         public App() 
10         {
11             this.Startup += this.OnStartup;
12             this.Exit += this.OnExit;
13             this.UnhandledException += this.Application_UnhandledException;
14 
15             InitializeComponent();
16         }
17 
18         private void OnStartup(object sender, StartupEventArgs e)
19         {
20             var page = new Page();
21             // Read application parameter
22             var imageSourceUrl = string.Empty;
23             int viewCountInteger = 0;
24             if (e.InitParams.Count > 0)
25             {
26                 var viewCount = string.Empty;
27                 if (e.InitParams.ContainsKey("ImageSourceUrl"))
28                     imageSourceUrl = HttpUtility.HtmlDecode(e.InitParams["ImageSourceUrl"]);
29                 if (e.InitParams.ContainsKey("ViewCount")) viewCount = e.InitParams["ViewCount"];
30                 // Load the main control here
31                 if (!string.IsNullOrEmpty(viewCount))
32                     int.TryParse(viewCount, out viewCountInteger);
33             }
34             
35             page.SetImageSource(imageSourceUrl);
36             page.SetViewCount(viewCountInteger);
37             this.RootVisual = page;
38         }
39 
40         private void OnExit(object sender, EventArgs e) 
41         {
42         }
43 
44         private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) 
45         {
46             // If the app is running outside of the debugger then report the exception using
47             // the browser's exception mechanism. On IE this will display it a yellow alert 
48             // icon in the status bar and Firefox will display a script error.
49             if (!System.Diagnostics.Debugger.IsAttached)
50             {
51                 // NOTE: This will allow the application to continue running after an exception has been thrown
52                 // but not handled. 
53                 // For production applications this error handling should be replaced with something that will 
54                 // report the error to the website and stop the application.
55                 e.Handled = true;
56                 Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
57             }
58         }
59 
60         private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e)
61         {
62             try
63             {
64                 string errorMsg = e.ExceptionObject.Message + @"\n" + e.ExceptionObject.StackTrace;
65                 errorMsg = errorMsg.Replace("\"", "\\\"").Replace("\r\n", @"\n");
66 
67                 System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight 2 Application " + errorMsg + "\");");
68             }
69             catch (Exception)
70             {
71             }
72         }
73     }
74 }

 

Page.xaml.cs

 1 using System;
 2 using System.Windows;
 3 using System.Windows.Browser;
 4 using System.Windows.Controls;
 5 using System.Windows.Media.Imaging;
 6 
 7 namespace Avatar
 8 {
 9     public partial class Page : UserControl
10     {
11         public Page()
12         {
13             // Required to initialize variables
14             InitializeComponent();
15             
16         }
17         public void SetImageSource(string imageSourceUrl)
18         {
19             if (!string.IsNullOrEmpty(imageSourceUrl))
20             {
21                 var url = new Uri(imageSourceUrl, UriKind.RelativeOrAbsolute);
22                 if (!url.IsAbsoluteUri)
23                 {
24                     url = new Uri(HtmlPage.Document.DocumentUri, url);
25                 }
26                 var image = new BitmapImage(url);
27                 Photo.ImageFailed += Photo_ImageFailed;
28                 PhotoShadow.ImageFailed += Photo_ImageFailed;
29                 Photo.ImageSource = image;
30                 PhotoShadow.ImageSource = image;
31             }
32         }
33         public void SetViewCount(int viewCount)
34         {
35             ViewCount.Text = viewCount.ToString();
36             ViewCountShadow.Text = viewCount.ToString();
37         }
38         void Photo_ImageFailed(object sender, ExceptionRoutedEventArgs e)
39         {
40         }
41     }
42 }

 

Note: You must get absolute Url for downloading photo with query string, see line 21-25 above. Silverlight will ignored query string if you are not provide absolute url for image source.

 

Grab DOM using jQuery

jQyery is very powerful tool for DOM manipulation. You can query and modify DOM with single line of code. Before query the DOM, you should be knows the DOM structure of page. Target of DOM is the avatar image. Open IE development toolbar to get the DOM of avatar. Find ID or CSS classes that used by Avatar to be replaced by Silverlight avatar.

image

From this information you can analyze that every blog entry placed inside DIV element with content_main_con_be CSS class. This DIV element contain view count and avatar image DIV in first and second child element. Based on this information, you can query the DOM using jQuery as script in line number 11 and 12 below.

 1 /*
 2     Filename: avatar.js
 3     Project : INDC Geeks
 4     Ver.    : 1.0
 5     Date    : March, 4th 2009
 6     Author  : Ahmad Masykur - www.masykur.web.id
 7 */
 8 
 9 $(document).ready(function() {
10     if (Silverlight.isInstalled('2.0')) {
11         var viewCountElements = $("div.content_main_con_be div:nth-child(1) > span:even");
12         var pictureBoxes = $("div.content_main_con_be div:nth-child(2)")
13         pictureBoxes.each(function(i, element) {
14             $(element).width(132).height(130);
15             var imageSourceUrl = $('img', element).attr('src');
16             createSilverlight(element, imageSourceUrl, $(viewCountElements[i]).text());
17         });
18         $("div.content_main_con_be div:nth-child(1)").hide();
19     }
20 });
21 
22 function createSilverlight(host, imageSourceUrl, viewCount) {
23     Silverlight.createObject(
24         '/ClientBin/Avatar.xap?v=0.2',
25         host, host +"_Plugin",
26         {
27             width: "100%", height: "100%",
28             background: "#E8CFB0", 
29             version: "2.0.31005.0" 
30         },
31         { onLoad: null },
32         'ImageSourceUrl=' + imageSourceUrl + ', ViewCount=' + viewCount);
33 }
34 

Description of script above are.

  • The script above will be execute when DOM is ready (evaluated in line 9).
  • Line 10 will verify if Silverlight 2 is installed in the machine. If Silverlight 2 is installed, DOM will be replaced with Silverlight object.
  • Line 11 and 12 is getting view counter and picture box elements.
  • Line 13: Make a loop the selected DOM. 
  • Line 14: Set the width and height of element that will be used for Silverlight host
  • Line 15: Get image Url information from IMG element
  • Line 16: Create Silvelight object using javascript.
  • Line 22-33 is function to create Silverlight object.
  • Line 32: Set InitParams value to be passing to Silverlight application.

This script required Silverlight.js and jQuery 1.3.2. The last steps are upload xap file of Silverlight application and required scripts also included the script above, Silverlight.js and jquery-1.3.2.min.js into blog.master of theme.

<script src="/JavaScripts/Silverlight.js" type="text/javascript"></script> 
<script src="/JavaScripts/jquery-1.3.2.min.js" type="text/javascript"></script>
<script src="/JavaScripts/avatar.js" type="text/javascript"></script>

Finally, the geeks portal have a new theme with Silverlight avatar. This avatar will available both installed Silverlight plung-ins or not. User will see HTML version of avatar if they don't have Silverlight plug-ins installed on the machine.

image

I would like to say thank you to Wely and Naren that support me to make it running well in geeks portal.


Categories: Silverlight
Permalink | Comments (3) | Post RSSRSS comment feed