In my previous post, GEOIP – Getting Started, I mentioned that I would illustrate how to actually use the GeoIP components, and here it is!
I’ll start with a personalization example. For this example we have a tab component that will have content specified for different US states. When a visitor comes to the site from Georgia, for example, they will be presented with a different set of content than a visitor from Ohio.
First, I’ll show the backing template. Our TabByState template contains a single-line text field for a title, a multilist field for state selection, a checkbox to indicate if it should be shown by default and a couple of inherited fields from our framework.
I’ve created instances of the template for a view states and regions.
Nothing spectacular here, the real fun comes when I add in the component. I start by launching the Experience Editor for a test page that I’m working with.
Then add in the TabsByState rendering component, leaving an empty datasource. Logic within the component will grab the items marked by the UseForNonStateMatches field to populate the component. Once the component is added I press the personalization button from the context menu of the component.
The Personalize the Component dialog has various options to get started with personalization. If I check the ‘Enable personalization of component design’ option, it allows me to swap out for different components. That’s not needed for this instance since I’m just updating the datasource of the component based on specified conditions. To start specifying the conditions, I press the ‘New Condition’ button.
I’ll give the condition a meaningful name in the Condition Name field.
For this example, I’ve just started setting up 3 conditions. The next part is to setup the condition logic to be used and that is done pressing the ‘Edit’ button in the condition frame.
For the purposes of this example, I’m only interested in the GeoIp options that are available. There are various other options that can accommodate most if not all personalization needs. I’ll select the option from GeoIp ‘where the region compares to specific value’. Region is actually the state abbreviation when GeoIp retrieves the data.
As the comparison value I’m selecting ‘is equal to’, because we’ll be matching against the state abbreviation the GeoIp provides.
Next, I need to specify the ‘specific value’ to compare against. By pressing the link a text box will display allowing me to input the text to use.
In the below example I’m configuring the condition for Georgia, so I’ve set the text to compare against to ‘GA’.
After setting the comparison values, I select the datasource item to use when that condition is met.
Here is the end result of my conditions with the datasources set in the ‘Personalize Content:’ field for each.
When I switch back to the Experience Editor view there are new options available in the context menu. These options correspond to the conditions that were just set. Selecting a condition from the drop-down list will reload the component with the specified datasource for that condition.
Here I used the list to set the condition to Georgia.
From the context menu drop down you can view what the actual comparison specification is for the selected condition.
Sitecore 8.1 includes some built in GeoIp and Device Detection options that can be accessed using the ‘Explore’ option from the Mode section in the Experience Editor.
Selecting the left arrow in the Explorer view brings up the Settings. From the Visitor Information section’s GeoIp tab, I can use the map to select a location to test the component with. This is a pretty cool utility, but during my testing it didn’t always resolve as expected. I did want to point it out because as the kinks get worked out it will be very useful.
Select the location from the map and press the Apply button and it will update the component accordingly.
That’s it for the front-end personalization piece. Below is the code from the mvc controller agent that actually does the work. The framework used by this project is called ‘Ignition’ and will be available in the near future, so keep an eye on the Perficient blogs to learn more about it.
using Domain.Sc.ViewModels.Tabs; using Common.Core; using Common.Core.MVC; using Common.Core.Utils; using Domain.Data.Modules.Settings; using Domain.Data.Modules.Tabs; using System.Collections.Generic; using System.Linq; namespace Domain.Sc.Controllers.Tabs { public class TabsByStateAgent : AbstractViewAgent<TabsByStateViewModel> { public TabsByStateAgent(IRepository repository, SitecoreData sitecoreData) : base(repository, sitecoreData) { } public override void PopulateModel() { var dS = Datasource as IStateSetting; var useDefault = true; List<ITabsByState> tabs; var tabFolder = Repository.Service.GetItem<ITabFolder>(Constants.ItemId.TabFolder); if (dS == null) { tabs = tabFolder.BaseChildren.OfType<ITabsByState>().Where(x => x.UseForNonStateMatches).ToList(); } else { useDefault = false; tabs = tabFolder.BaseChildren.OfType<ITabsByState>().ToList(); } ViewModel.Tabs = new List<ITabsByState>(); foreach (var tab in tabs) { if (!useDefault) { foreach (var state in tab.States) { if (state.Name == dS.Name) { ViewModel.Tabs.Add(tab); } } } else { ViewModel.Tabs.Add(tab); } } } } }
Personalization with GeoIp is really cool and provides a lot of functionality from a front-end standpoint. On the back-end side of things using the functionality is very easy. I have a simple form with a text box for a zip code and a button to find shops around that zip code. It helps the user experience if their zip code is pre-populated by saving them the time of typing it in. By default if the service is not available or GeoIp wasn’t part of the solution, I would see something like this.
With a few lines of code, I can access the information that GeoIp pulls from the user’s ip address when they visit the page. First, I check to see if the Tracker data along with the GeoData is available and if not the user will be presented with the generic ‘Zip Code’ text. If the data is available, though, I can populate the zip code text using the GeoData’s PostalCode property.
using System.Linq; using Domain.Sc.ViewModels.Forms; using Common.Core; using Common.Core.Models.Settings; using Common.Core.MVC; using Common.Core.Utils; using Sitecore.Analytics; namespace Domain.Sc.Controllers.Forms { public class ZipCodeFormAgent : AbstractViewAgent<ZipCodeFormViewModel> { public ZipCodeFormAgent(IRepository repository, SitecoreData sitecoreData) : base(repository, sitecoreData) { } public override void PopulateModel() { ViewModel.FormTags = Datasource.BaseChildren.OfType<IKeyValueSetting>(); if (Tracker.Current == null || Tracker.Current.Interaction == null || Tracker.Current.Interaction.GeoData == null) { ViewModel.CurrentZipCode = string.Empty; return; } ViewModel.CurrentZipCode = Tracker.Current.Interaction.GeoData.PostalCode == "N/A" ? string.Empty : Tracker.Current.Interaction.GeoData.PostalCode; } } }
That chunk of code produces the following results. For these to screenshots I’m using the Chrome extension to spoof the ip address into the page because of some unresolved issues I ran into with the Explorer view.
That’s how to work with GeoIp in some very simple use cases. I hope this has been informative and feel free to comment with any questions.
Thanks