Showing posts with label XML. Show all posts
Showing posts with label XML. Show all posts

Adding title attribute to Social Identity Providers [IDPs] buttons when using Azure AD B2C custom policies

This is a simple post that shows how you can achieve exactly what the blog title says...

You'll need only some jQuery code once you enable JavaScript for the custom policy.

By default the social login buttons are shown only with text. They don't have title attributes that are used as tooltips by default when hovering the button during 2 seconds or so.

Let's say that for the social IDPs buttons we want to show only the button logo instead of the button text to make the screen overall look & feel cleaner. However it'd be nice to show a title\tooltip to inform the user what IDP that button refers to in case they don't get it by only seeing the logo.

To accomplish that follow these 2 straightforward steps:

1 - Enable JavaScript execution inside UserJourneyBehaviors in your Azure B2C custom sign in\sing up policy .xml file:

<UserJourneyBehaviors>
  ...
  
  <ScriptExecution>Allow</ScriptExecution>
</UserJourneyBehaviors>

2 - Add this code in the corresponding policy signin.html page:

<script>

    // Adding title to each Social button...
    $(".accountButton").each(function (index)
    {
      var title = $(this).text();

      $(this).prop('title', title);
    });

  </script>

Once loading the B2C login page you should see something as this when you hover your cursor over any social IDP button:

Enabling and using JavaScript allows us to extend functionality in many places.

Line prefixer suffixer in C#

I extracted a lot of Ids from a database table and needed to pass such Ids as a parameter to a webservice method. The webservice method was expecting a parameter of type List<long>. I didn’t find a way of passing such a list to the webservice using the built in webservice form constructed by Visual Studio. The cause is that a List<long> isn’t a primitive type.

Talking with my peers I learned of a tool called soapUI. It’s a tool used to test webservices. Using it I could pass the list of Ids.

I created a new project in soapUI passing to it the webservice WSDL URL and I was ready to go.

 soapUI New Project

New soapUI Project

This is the value I’ve put in Initial WSDL/WADL:

http://localhost:7777/WebServices/MyWebserviceName.asmx?WSDL

After clicking OK, soapUI will then load the webservice definition.

Clicking in Request 1 as shown in the following picture, the XML of a SOAP envelope appears so that we can test the webservice method.

soapUI Request 1

The problem now was that I had a file called “input.txt” with only the Ids – each one in its proper line. The XML of the SOAP envelope expect that each id be passed in the format:

<ns:long>?</ns:long>

For example,

<ns:long>7</ns:long>

As we can observe, my input data don’t fit the pattern required by the XML.

To put my data in conformity with the XML I created a small but useful application called LinePrefixerSuffixer that receives the name of an input file containing the the initial data, the text to be “prefixed” in the start of each line, the text to be “suffixed” in the end of each line of the file and the name of the output file.

So for example, to comply with the above pattern, I’d call the console application with:

LinePrefixerSuffixer input.txt “<ns:long>” “</ns:long>” output.txt

Let’s say I have a file called input.txt with 1000 numbers in the same directory of the LinePrefixerSuffixer.exe executable.

Each line of the input.txt file has a number as:

1
2
3
4
5
6
7
.
.
.

Running the above command line in the command prompt I’d get a file called output.txt with each line now in the format I want, that is:

<ns:long>1</ns:long>
<ns:long>2</ns:long>
<ns:long>3</ns:long>
<ns:long>4</ns:long>
<ns:long>5</ns:long>
<ns:long>6</ns:long>
<ns:long>7</ns:long>
. 
. 
.

Line Prefixer Suffixer

The C# code of the app is as follow:

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

namespace LinePrefixerSuffixer
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // Read in all lines of the file using query expression (LINQ).
                // I "prefix" the start of each line with the content of args[1] and
                // "suffix" the end of each line with the content of args[2].
                IEnumerable<string> fileLines = from line in File.ReadAllLines(args[0])
                                                select args[1] + line + args[2];

                // Writing the prefixed and suffixed file lines to a file named with the content of args[3].
                File.WriteAllLines(args[3], fileLines.ToArray());

                Console.WriteLine("Operation done.");
            }
            catch(Exception e)
            {
                Console.WriteLine("Use: LinePrefixerSuffixer <input.txt> prefix suffix <output.txt>");
            }
        }
    }
}

Now I can pass the content of the output.txt file to soapUI without worrying about having to manually prefix/suffix each line of my input.txt file:

soapUI Request 1

Summary
In this post we saw how to build a simple but powerful application that prefixes and suffixes each line of a file.

We’ve used concepts related to file handling and LINQ and with only 4 lines of code we could manage to accomplish the task.

I think this shows how powerful modern programming languages as C# enables a clean and beautiful coding experience.

Hope this helps.

Visual Studio C# Console Application
You can get the Microsoft Visual Studio Project and the app executable at:

http://leniel.googlepages.com/LinePrefixerSuffixer.zip

Note: As this program uses LINQ, you must have Microsoft .NET Framework 3.5 runtime libraries installed on you computer. You can get it at:

http://www.microsoft.com/downloads/details.aspx?FamilyID=333325fd-ae52-4e35-b531-508d977d32a6&DisplayLang=en

References
[1] soapUI - the Web Services Testing tool. Available at <http://www.soapui.org>. Accessed on January 20, 2009.

[2] Sam Allen. File Handling - C#. Available at <http://dotnetperls.com/Content/File-Handling.aspx>. Accessed on January 20, 2009.

[3] LINQ. The LINQ Project. Available at <http://msdn.microsoft.com/en-us/netframework/aa904594.aspx>. Accessed on January 20, 2008.

[4] LINQ. Language Integrated Query. Available at <http://www.leniel.net/2008/01/linq-language-integrated-query.html>. Accessed on January 20, 2008.

Backup blogger posts with Blogger Backup

If you want to use Blogger’s built in function take a look in this question at StackOverflow.
Updated on 08-10-2010

I just wanted to backup my blogger posts. I searched for a tool that could automate the process and fortunately I found a pretty good piece of software that does just that. Its name is Blogger Backup Utility.

The software enables you to backup your posts with a high degree of customization. You can backup all the blogs you have. Each one will have its own backup settings.

You can choose if you want to save posts' comments, in what format (one Atom XML file per post or all the posts in a single file) to save the posts, if you want only the most recent posts or the ones included in the specified data range.

See the screenshot of the main window bellow:

BloggerBackUpUtilityMainWindow

Clicking on the button Backup File Naming you'll have the chance of specifying the naming options for the backup files.

There are to configurable options: Folder Name Options and Post File Name Options.

In Folder Name Options you can configure the directory structure in which your posts will be saved.

In Post File Name Options you can configure the name of each post.

In both Folder Name and Post File Name, you can chose from a diverse array of patterns to form the name of the directory structure and posts.

See the screenshot of the Backup File Naming Options:

BloggerBackUpUtilityNamingOptions

After setting up your blog configurations you can click the button Backup Post in the Main Window.

A progress bar on the status bar and list of processed posts will show you the backup process.

The inverse process is also possible, that is, to restore your blog posts, just click on Restore Posts in the Main Windows.

It's really simple, fast and efficient. It does what it's meant to do.

The app only backups in the Atom file format that is an XML file.

Bellow is the structure of the XML that represents the backup copy of this post:

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Backup blogger posts with Blogger Backup</title>
  <id>tag:blogger.com,1999:blog-4926735770070291800.post-7337460476756797508</id>
  <link href="http://lenielmacaferi.blogspot.com/2008/05/backup-blogger-posts-with-blogger.html" rel="alternate" type="text/html" title="Backup blogger posts with Blogger Backup" />
  <link href="http://www.blogger.com/comment.g?blogID=4926735770070291800&amp;postID=7337460476756797508" rel="replies" type="text/html" title="0 Comments" />
  ...
<author> <name>Leniel Macaferi</name> <email>noreply@blogger.com</email> <uri>http://www.blogger.com/profile/17950821674268154143</uri> </author> <category term="Blogger" scheme="http://www.blogger.com/atom/ns#" /> ...
<content type="html"> ...
</content> <updated>2008-05-15T03:45:31-03:00</updated> <published>2008-05-15T03:08:00-03:00</published> </entry>

I wondered how I could extract only the content that interested me and present it in a different format as HTML.

In a next post I'll show you how to transform the XML returned by Blogger Backup into an HTML file. To that end I'll use a XSLT file.

Where to download Blogger Backup Utility?
You can find Blogger Backup at CodePlex at the following address:
http://www.codeplex.com/bloggerbackup

It is developed by only one guy named Greg.

This is the definition given by the author:

The Blogger Backup utility is intended to be a simple utility to backup to local disk your Blogger posts.

Using the GData C# Library, the utility will walk backward in time, from your latest post to your last, saving each post to a local Atom/XML file.

I congratulated him and wrote on the project's page at CodePlex that the addition of the HTML format when saving the posts would be a good feature in case someone wanted to save the posts in an HTML fashion instead of XML.

For more screenshots with descriptions, follow this link:
http://www.codeplex.com/bloggerbackup/Wiki/View.aspx?title=Screenshots&referringTitle=Home

Adding a custom Google Map on a web page

Google mapOn last January I started playing around with the Google Maps API that is especially intended to instigate the coding skills of the developers around the world. At that time I created a simple page to host a map that showed the directions from a start city to a destination city. Then I did other test in which I used Microsoft Visual C# 2008 Express to retrieve and parse the XML data generated by a Google Map search query. I was curious about how I could send a search to Google Map webservice and as a result get back the structured data to be consumed by some application. I just wanted to explore and see how it worked. At that time I set plans to blog about the Google Map functionally and so today I'm doing just that.

As the title states, I'm going to list here the steps necessary to add a Google Map on a web page and I will comment about the drawbacks I had to overcome to get it functioning the way I wanted.

The map I'll show has different markers. When one of these markers is clicked an info windows is opened to display some useful information. For a real example look at the map I place here on this blog. It's on the sidebar. As you can see the map starts in a hybrid fashion, that is, it shows normal and satellite views. The zoom level is adjusted based on the bounds of the existing markers. I'll detail what is necessary to do to get a map just like the one you see on this blog so that you can make your own.

The programming language used to construct the map is basically JavaScript. It's a good idea to check the Google Maps API documentation in order to get acquainted with the object types used when coding the map. For more information regarding a specific map object, refer to the documentation.

The steps I followed to get a functional map were:

  1. Obtain a Google Maps API key at the Sign Up for the Google Maps API form
    The Google Maps API lets you embed Google Maps in your own web pages. A single Maps API key is valid for a single "directory" or domain. At the end of the sign up form just enter your domain name and you'll be given a key. Without this key your maps won't function.
  2. Implement the map code

The following is the code I used to build the map:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
    <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
      <title>Leniel Macaferi's blog - Places I cite on this blog - Google Maps JavaScript API Example: Asynchronous Data Retrieval</title>
      <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YourKey" type="text/javascript"></script>

      <script type="text/javascript">
      function initialize()
      {
        if(GBrowserIsCompatible())
        {
          <!-- Create a base icon for all of our markers that specifies the shadow, icon dimensions, etc. -->
          var baseIcon = new GIcon();
          baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
          baseIcon.iconSize = new GSize(20, 34);
          baseIcon.shadowSize = new GSize(37, 34);
          baseIcon.iconAnchor = new GPoint(9, 34);
          baseIcon.infoWindowAnchor = new GPoint(9, 2);
          baseIcon.infoShadowAnchor = new GPoint(18, 25);

          <!-- Creates a marker whose info window displays the letter corresponding to the given index. -->
          function createMarker(point, index, tooltip, html)
          {
            <!-- Create a lettered icon for this point using our icon class -->
            var letter = String.fromCharCode("A".charCodeAt(0) + index);
            var letteredIcon = new GIcon(baseIcon);
            letteredIcon.image = "http://www.google.com/mapfiles/marker" + letter + ".png";

            <!-- Set up our GMarkerOptions object -->
            markerOptions = { icon:letteredIcon, title:tooltip};

            var marker = new GMarker(point, markerOptions);

            GEvent.addListener(marker, "click", function()
            {
              marker.openInfoWindowHtml(html);
            });

            return marker;
          }

          <!-- Creating the map and setting its essential properties -->
          var map = new GMap2(document.getElementById("map_canvas"));
          map.setCenter(new GLatLng(0,0),0);
          map.setMapType(G_HYBRID_MAP);
          map.addControl(new GLargeMapControl());
          map.addControl(new GMapTypeControl());

          var bounds = new GLatLngBounds();

          <!-- Download the data in data.xml and load it on the map. The format we expect is:
               <markers>
                 <marker lat="37.441" lng="-122.141" tooltip="Tooltip" html="HTML Code" />
                 <marker lat="37.322" lng="-121.213" tooltip="Tooltip" html="HTML Code" />
               </markers> -->
         GDownloadUrl("googlemap.xml", function(data)
         {
           var xml = GXml.parse(data);

           var markers = xml.documentElement.getElementsByTagName("marker");

           for(var i = 0; i < markers.length; i++)
           {
             var latlng = new GLatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));

             var tooltip = markers[i].getAttribute("tooltip");

             var html = markers[i].getAttribute("html");

             map.addOverlay(createMarker(latlng, i, tooltip, html));

             bounds.extend(latlng);
           }

           map.setZoom(map.getBoundsZoomLevel(bounds));

           map.setCenter(bounds.getCenter());
         });
       }
     }

     </script>
  </head>

  <body onload="initialize()" onunload="GUnload()" style="width:265px; height:300px; margin:0px; padding:0px;">
<div id="map_canvas" style="float:left; width:265px; height:300px; margin:0px; padding:0px;"></div>
</body>
</html>
Let's see the first java script tag right beneath the title tag
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YourKey" type="text/javascript"></script>
Note the YourKey value. Substitute this value with you own Google Maps API key. The JavaScript function initialize() is called when the page hosting the map is loaded. Look at the body tag:
<body onload="initialize()" ...
The initialize function firstly checks if the client browser is compatible with Google Maps with the GBrowserIsCompatible function:
if(GBrowserIsCompatible())
{
  ...
}
If this is the case, it's possible to go ahead and start the map construction. I won't comment the code I reuse. I'll just pass by it and brief explain what it does. Expect me explaining the other parts for sure. See the following lines:
<!-- Create a base icon for all of our markers that specifies the shadow, icon dimensions, etc. -->
var baseIcon = new GIcon();
baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
baseIcon.iconSize = new GSize(20, 34);
baseIcon.shadowSize = new GSize(37, 34);
baseIcon.iconAnchor = new GPoint(9, 34);
baseIcon.infoWindowAnchor = new GPoint(9, 2);
baseIcon.infoShadowAnchor = new GPoint(18, 25);
The above lines of code are defining a standard icon that'll be used to construct the markers on map.

The function createMarker does a really beautiful work. See it bellow:

<!-- Creates a marker whose info window displays the letter corresponding
to the given index. -->
function createMarker(point, index, tooltip, html)
{
  <!-- Create a lettered icon for this point using our icon class -->
  var letter = String.fromCharCode("A".charCodeAt(0) + index);
var letteredIcon = new GIcon(baseIcon);
letteredIcon.image = "http://www.google.com/mapfiles/marker" + letter + ".png";

  <!-- Set up our GMarkerOptions object -->
  markerOptions = { icon:letteredIcon, title:tooltip};

  var marker = new GMarker(point, markerOptions);

  GEvent.addListener(marker, "click", function()
  {
    marker.openInfoWindowHtml(html);
  });

  return marker;
}
What does it do? I receives a point, more specifically a GPoint, and index, a tooltip, and a html code. It then creates a GIcon using Google's letter images for each marker, based on its index. The markerOptions variable has a type of GMarkerOptions and stores the attributes that has do with the icon properties as for example the title that receives the tooltip parameter value. For each maker it's set up an event handler for the click event. When the marker is clicked its openInfoWindowHtml method is called with the html content passed as a parameter. The createMarker function then returns the new created marker that will be added to the map overlay.

What follows is the instantiation of the map:

var map = new GMap2(document.getElementById("map_canvas"));
A new object of type GMap2 is created. This object is instantiated in order to create a map. This is the central class in the API. Everything else is auxiliary. The object constructor accepts as argument an HTML container, which is typically a DIV element. In this case the id of the DIV element I use is map_canvas. If you look at the div tag that is inside the body tag you'll see the map_canvas id applied to the div.
<div id="map_canvas" ...
Next we center the map with zero values. I'll explain later why I do so. Then the map type is set:
map.setCenter(new GLatLng(0,0),0);
map.setMapType(G_HYBRID_MAP);
The function setMapType can accept the following list of values:
  • G_NORMAL_MAP- the default view
  • G_SATELLITE_MAP - showing Google Earth satellite images
  • G_HYBRID_MAP - showing a mixture of normal and satellite views
  • G_DEFAULT_MAP_TYPES - an array of these three types, useful for iterative processing
The next line of code uses a GSmallMapControl object to add to the map a control with buttons to pan in four directions, and zoom in and zoom out, and a zoom slider:
map.addControl(new GSmallMapControl());
The last line of code to mount the basic map framework uses a GMapTypeControl object to add a standard map type control for selecting and switching between supported map types via buttons:
map.addControl(new GMapTypeControl());
This line of code has to do with the zoom that will be applied to the map. A variable called bound is declared and its type is GLatLngBounds. It will be used afterwards to set the zoom level of the map. This variable represents a rectangle in geographical coordinates, including one that crosses the 180 degrees meridian:
var bounds = new GLatLngBounds();
After constructing the framework it's time to populate the map with the desired data. That's the exciting part. Let's get to it.

As the green commentary lines state there's a predefined data format to structure the bits relative to the markers (GMarker class) that will be shown on the map. In this post I'm using a XML file called googlemap.xml to store the markers' data. The data is composed of lat (latitude), lng (longitute), tooltip (title of the marker) and html (any text). What is really cool is that you can format the text inside the html value using HTML and CSS. The text will be displayed inside the marker's info window. Altough I don't use formating in my XML file you're being infored that this is possible. Bellow is the content of the file:

<markers>
<!-- Don't use copy and paste on this XML file, use "View Source" or "Save As"
What the browser displays is *interpreted* XML, not XML source. -->
  <marker lat="-22.522778" lng="-44.103889" tooltip="Hello World!" html='Hello World!"/>
  <marker lat="-23.209862" lng="-45.876168" tooltip="Jesus Message" html="I'm the way, the truth and the life. John 14:6" />
</markers>
To consume this data we must make a call to the GDownloadUrl function. This function provides a convenient way to asynchronously retrieve a resource identified by a URL. Notice that, since the XmlHttpRequest object is used to execute the request, it is subject to the same-origin restriction of cross-site scripting, i.e. the URL must refer to the same server as the URL of the current document that executes this code. This is known as the Same Origin Policy. Therefore, it is usually redundant to use an absolute URL for the url argument, and it is better to use an absolute or relative path only.

This explanation is really important. While implementing the map you see on the sidebar of this blog I tried to store the googlemap.xml file on a domain different from the one of this blog, that is, I placed the XML data file on leniel.googlepages.com and was trying to consume its content at lenielmacaferi.blogspot.com. It's not possible because of cross-domain scripting limitations. It's a security issue! So what I did? I thought about other way of implementing it. I created the map host page at leniel.googlepages.com and used an IFrame to show the page on the sidebar of this blog. Simple, isn't it? Doing so, there's no security issue since I'm running the above JavaScript and consuming the XML data on the same domain leniel.googlepages.com. An inconvenience if I can call it this way is that I had to get another Google Maps API key to use on the other domain. It's not a inconvenience at all! :)

That said, let's move on.

The GDownloadUrl function has the following signature:

GDownloadUrl(url, onload, postBody?, postContentType?)
As you can see I'm using just two of the parameters above when I call the function in the code:
GDownloadUrl("googlemap.xml", function(data)
{
  ...
});
It then retrieves the resource from the given URL and calls the onload function, in this case function with the text of the document as first argument.

Now what must be done is the parsing operation. We need to read each line of the markers' XML file and extract its individual components such as lat, lng, html and tooltip. To that end we declare a variable named xml that will store the GXml parsed content. Note the use of the parse static method that consumes the data we got from the googlemap.xml:

var xml = GXml.parse(data);
After parsing it's now created a variable named markers that will store the individual nodes (markers) of the XML file:
var markers = xml.documentElement.getElementsByTagName("marker");
As you can see the getElementByTagName function gets the marker elements from the XML file. Each marker has this form:
<marker lat="-23.209862" lng="-45.876168" tooltip="Jesus Message" html="I'm the way, the truth and the life. John 14:6" />
In the next step an iteration takes place over the collection of markers with a for loop:
for(var i = 0; i < markers.length; i++)
{
  ...
}
The next instruction instantiates a new object of type GLatLng so that we can get the lat and lng values of each marker and store the same in the latlng variable:
var latlng = new GLatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));
It's time to retrieve the html code and tooltip values that will be shown on each mark. To that end are the following to lines:
var html = markers[i].getAttribute("html");

var tooltip = markers[i].getAttribute("tooltip");
A GMarker marks a position on the map. It implements the GOverlay interface and thus is added to the map using the GMap2.addOverlay() method. Each marker is created using its respective lat and lng values along with other relevant data you want as is the case of the following line of code. This is without doubt the trickiest part of the code :). I mean, after we call the createMarker function defined and explained above:
map.addOverlay(createMarker(latlng, i, tooltip, html));
For the purpose of setting a nice zoom on the map I use the bounds variable:
bounds.extend(latlng);
This variable is extended in conformity with the largest latitude and longitude. The above line is the last one pertaining to the loop and now we're almost done. We have two more lines of code to go through to finalize the map construction:
map.setZoom(map.getBoundsZoomLevel(bounds));
map.setCenter(bounds.getCenter());
The first line sets the zoom using the bounds variable and the second one center the focus on the map using the getCenter method from the bounds variable. That's it. The map is ready!

You can see this map running at this URL: http://leniel.googlepages.com/googlemap.html

Final notes
Pay close attention to the written code. If you change a letter in the name of a variable for example, your code won't function and you'll probably not see the map.

If loading the information from XML as is the case of this post, replace '<' and '>' characters with &lt; and &gt;. For example: &lt;img src="image.jpg" width=150 height=100&gt;

There are plenty of excellent material about the Google Maps API on the internet and the possibilities are uncountable. Just let your imagination flow and build amazing, astonishing maps that fit your will.

References
The code I present on this post is a mix from a variety of sources and some of them are listed bellow. I just adapted it so that I could get the result I wanted.

The following links are great sources of information. Particularly, take a look at Mike's Little Web Page. He has a bunch of great stuff about Google Maps API.

Mike Little's Web Page
http://www.econym.demon.co.uk/

Google Maps API Tutorial
http://econym.googlepages.com/index.htm

Fitting the map to the data
http://econym.googlepages.com/basic14.htm

Links and Images, etc.
http://econym.googlepages.com/basic6.htm http://econym.googlepages.com/example_map6b.htm

Services - Google Maps API - Google Code http://code.google.com/apis/maps/documentation/services.html

Google Maps JavaScript API Example: Asynchronous Data Retrieval http://code.google.com/apis/maps/documentation/examples/xhr-requests.html

Google Maps JavaScript API Example: Custom Icon http://code.google.com/apis/maps/documentation/examples/icon-custom.html