Mobile Visitor Group criteria for EPiServer

We have heaps of requests from our client. There is a good reference here and we little a bit extended this using below approach, to define if the current user is on mobile or not and show, hide content based on this concept. First step is to define model and this will be stored in Dynamic  Data Store (DDS). This will be stored so CMS can use it to apply the criteria:

    public class BrowserModel : CriterionModelBase
    {
        [DojoWidget(
            SelectionFactoryType = typeof (EnumSelectionFactory),
            LabelTranslationKey = "/shell/cms/visitorgroups/criteria/browser/browsertype",
            AdditionalOptions = "{ selectOnClick: true }"),
         Required]
        public BrowserType Browser { get; set; }

        public override ICriterionModel Copy()
        {
            return ShallowCopy();
        }
    }

    public enum BrowserType
    {
        Desktop,
        Mobile
    }

Second step is to define a criteria and the logic which make decision about if the current user is on mobile or not! We are using  current user request UserAgent:

[VisitorGroupCriterion(
        Category = "User Criteria",
        DisplayName = "Browser",
        Description = "Criterion that matches type of the user's browser",
        LanguagePath = "/shell/cms/visitorgroups/criteria/browser")]
    public class BrowserCriterion : CriterionBase<BrowserModel>
    {
        public override bool IsMatch(IPrincipal principal, HttpContextBase httpContext)
        {
            return MatchBrowserType(httpContext.Request.UserAgent);
        }

        protected virtual bool MatchBrowserType(string userAgent)
        {
            var os =
                new Regex(
                    @"(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino",
                    RegexOptions.IgnoreCase | RegexOptions.Multiline);
            var device =
                new Regex(
                    @"1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-",
                    RegexOptions.IgnoreCase | RegexOptions.Multiline);
            var deviceInfo = string.Empty;

            if (os.IsMatch(userAgent))
            {
                deviceInfo = os.Match(userAgent).Groups[0].Value;
            }

            if (device.IsMatch(userAgent.Substring(0, 4)))
            {
                deviceInfo += device.Match(userAgent).Groups[0].Value;
            }

            if (!string.IsNullOrEmpty(deviceInfo))
            {
                return Model.Browser == BrowserType.Mobile;
            }

            return Model.Browser == BrowserType.Desktop;
        }

Hope it can save you some time on writing custom code!

To exclude uploaded EPiServer Form file uploaded (FileUploadElementBlock) from EPiServer Find Index

There is a flues in EPiServer Form which all uploaded file can be indexed. To exclude uploaded file using EPiServer Form -> FileUploadElementBlock from EPiServer Find indexer you can go:

    [ModuleDependency(typeof(InitializationModule))]
    public class EPiServerFindInitialization : IInitializableModule
    {
        public void Initialize(InitializationEngine context)
        {
            ContentIndexer.Instance.Conventions.ForInstancesOf().ShouldIndex(ShouldIndexDocument);
        }

        public void Uninitialize(InitializationEngine context)
        {
        }

        bool ShouldIndexDocument(DocumentFileBase documentFileBase)
        {
            if (contentAssetHelper.Service.GetAssetOwner(documentFileBase.ContentLink) is FileUploadElementBlock)
            {
                IEnumerable result;
                ContentIndexer.Instance.TryDelete(documentFileBase, out result);

                return false;
            }

            return true;
        }

        readonly Injected contentAssetHelper;
    }

Solution Architect vs Agile

What is the definition of Architecture? There many definition but I like this one “defining a structured solution that meets all of the technical and operational requirements, while optimizing common quality attributes such as performance, security, and manageability”. It is very broad but what most of the people think of the architecture is a definition of how software structure should looks like but how much deep you should go? Is the job of solution architect is design the architecture and go away? In my opinion this is not going to work. Especially with Agile methodology it is hard to define all requirements upfront! So I think it is iterative process and solution architect needs to iteratively groom and adapt his solution. The architecture can’t be change too much because it would be expensive but the design could change. But is software architect needs to manage the team or based on Agile sole the team needs to be self-managed. I think solution architect needs to help team and there is no management. Solution architect needs to make sure his solution and design understood and it has been adapted properly and if there is any change needs to be done should be considered in next iteration or if it is blockage need to consider to change immediately. Solution architect can use code review as one of best tools to audit the design and making sure it adapted and communicated properly. I think solution architect need to read and write code, maybe more reading but should write some code to be hand on.

How to pass configuration to your custom editor in EPiServer

Recently I’m working on a project which has a requirement. We need focal point selector for an image. So the idea is you pick a focal point and application based on requested image size crop the image based on selected focal point. So I store the focal point (x,y) as a comma separated in string.

public class ImageFile : ImageData
{
	[UIHint("FocalPoint")]
	public virtual string FocalPoint { get; set; }
}

Now we want make the EPiServer custom editor named “FocalPoint”. There are many post about this so I ignore this part but what I need to pass current image URL to be passed to my editor. So for doing this we need EditorDescriptor as below:


	[EditorDescriptorRegistration(TargetType = typeof(string), UIHint = "FocalPoint")]
	public class FocalPointEditorDescriptor : EditorDescriptor
	{
		public FocalPointEditorDescriptor()
		{
			this.ClientEditingClass = "alloy.editors.FocalPointSelector";
		}
		public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable attributes)
		{
			base.ModifyMetadata(metadata, attributes);
		}
	}

Now we want to change the code to pass current image URL to editor, so editor can load the image and user can select the focal point. Code below is a magic which need to be injected into ModifyMetadata method.


			var contentDataMetadata = metadata as ContentDataMetadata;
			if (contentDataMetadata != null)
			{
				var imageFile = contentDataMetadata.OwnerContent as IContentMedia;
				if (imageFile != null)
				{
					metadata.EditorConfiguration["imageURL"] = UrlResolver.Current.GetUrl(imageFile.ContentLink);
				}
			}

And now we can access the value in our edit in JS:


define([
	"dojo/_base/connect",
	"dojo/_base/declare",
	"dijit/_CssStateMixin",
	"dijit/_Widget",
	"dijit/_TemplatedMixin",
	"dijit/_WidgetsInTemplateMixin",
	"epi/shell/widget/_ValueRequiredMixin",
	"dojo/dom",
	"dojo/on",
	"dojo/text!./templates/FocalPointSelector.html"],

	function (
		connect,
		declare,
		_CssStateMixin,
		_Widget,
		_TemplatedMixin,
		_WidgetsInTemplateMixin,
		_ValueRequiredMixin,
		dom,
		on,
		template) {

		return declare(
			"ras.editors.FocalPointSelector", [
				_Widget,
				_TemplatedMixin,
				_WidgetsInTemplateMixin,
				_CssStateMixin,
				_ValueRequiredMixin],
			{
				templateString: template,
				selector: null,
				intermediateChanges: false,
				image: null,
				value: null,
				onChange: function (value) { },
				postCreate: function () {
					this.image = dojo.create("img", { "style": "width:100%;height:100%", "src": this.imageURL }, this.domNode);
				}
			});
	});

And you can see “imageURL” is being passed to our javascript code and we can use it.

Do we really need accessible webiste

I’m currently working on website which should be accessible! What that means? I thought it could be waste of time to spend huge amount of time to make a website accessible because no one will use it. BUT just did some research and saw this video . I’m really surprised because in North America about %64 of blind people are advanced user of internet (link) so I think it is very important and I think most of websites need to be compatible with WCAG and first step to make this happen is to make famous web related frameworks (e.g. Angular) to be compatible with this. I really like to have comprehensive post about how to make this happen and a checklist for webmaster and developers to keep in mind. Unfortunately there is a good tool that help you to achieve. There are some and we used them but when we ask real user to use website they can’t because of dynamic structure and thing people designed these tools are not blind! So I really look to a post (perhaps series) about this.

Open Close Prinicple

Second SOLID principle, Open for extension and close for changes!

Wow how it is possible something can be open and close! I’m surprised! But it is possible you should design


public void Draw(Shape shape)
{
var point = CalculateStartPoint(shape);
if(shape is Rectangle)
{
DrawRectangle(point, shape);
}
else if (shape is Circle)
{
DrawCircle(point, shape);
}
}

Now think about you have new Shapre called Triangle so to make the Draw function working you need to change Draw function! So to extend your application you need to CHANGE EXISTING code which is violating OCP. So how it should be then?


public void Draw(Shape shape)
{
var point = CalculateStartPoint(shape);
shape.Draw(point);
}

Interesting, so I should add ‘Draw’ method to ‘Shape’ abstract and all implementation of ‘Shape’ should implement ‘Draw’. I like it now! So whenever you have ‘if’ or ‘switch’ based on ‘type’ of object there is a smell of OCP violation.

Ok but it is really hard to achieve this, many legacy code or in many situation it is really hard to make this working! That is correct so remember refactor it as much as possible to make sure there is no more room exists. This is engineering, finding balance and best approach!

Single Responsibility Principle

I had a problem to understand this for a long long time! You can’t believe how hard is it when you don’t understand the principle and try to adapt it! Mission impossible! Recently I spent some time again to read more about OOP principles and first step of SOLID is ‘S’.. Single Responsibility introduced by Uncle Bob. So let’s break it down:

Responsibility: Reason to change!!!

Single: One

Rephrase: One Reason to change!

Easy so what is a reason then? ACTOR!

OMG you just add more vocabulary!! What is Actor?

OK so we need to understand little a bit more of UML, Action means: An Actor models a type of role played by an entity that interacts with the subject (e.g., by exchanging signals and data), but which is external to the subject.

I don’t understand give me an example!!

Think below class as an example:

rich-domain-model

Employee class above has couple of functions. Is this class violating SRP? Yes! Why?

1. Load and Save functions, who will ask you to change them? DBAs

2. CalculatePay, CalculateHoliday functions, who will ask you to change them? Accountants

3. HoursWorked, HourlyRate functions, who will ask you to change them? Auditors

So three different “Actor”s exists in our example!

WOW! fascinating!

Now we understand that “Actor” and “Responsibility” is related to context. In some other context may be a class has one responsibility and in other context it has more than one. So for making your architecture and make sure you are not violating SRP you need to understand USE CASE and ACTOR and in REFACTOR process we can make decision about are we violating SRP!

Enjoy REFACTORING! And remember detecting violation SRP you need to understand user’s need and have good logic.

What is OOP

I recently started to think about what is really OOP. I thought it is a tool to model real word stuff! But this is what all programming is about! So rephrase it: OOP help you to model real word EASIER! But it is that correct? I don’t think that is comprehensive what that mean EASIER! I struggled for a while and end up with what is the meaning of EASIER! It solve the DEPENDENCY PROBLEM!!!!
Yay that is it!! Dependency of class and properties, class and other classes, class and interface! This seems silly but this is very important. The reason is now we think about dependency as a core or our design not the properties of each object. Now we think top to bottom! If you think about properties and method of classes FIRST you are thinking about details which is changing alot in our design and do not think enough about TOP LEVEL RELATIONSHIP. So how should I do more attention to TOP LEVEL design? Easy with TDD! So you start with top level which is class and you think about dependencies! And this good design will lead you for good design. I will start write about what is whole thing about with example! Keep in touch!

WCF RESTful .Net 4.0

In this post we want to introduce the project that hosts the WCF RESTful service and a client which is consuming the service with AJAX and jQeury. You need to have VS2010 and .Net 4.0 and being sure that you select the “.Net 4.0” when you want to create projects. So first step is creating new blank solution, then create new “WCF Service Application” and named it as “Server”:

Now have your service the only change that you need to apply is on web.config file. Let’s change it as below:

[cc lang=”XML” width=”100%”]

















[/cc]

Visual Studio has created the sample service, operation contract and data contract for you that should fine for our sample and your server for hosting RESTful service has been completed. Next step is to setup the client. You need to ensure that you have internet connection while loading the test client. Create new HTML file and place the code below as a content:

[cc lang=”HTML” width=”100%”]








[/cc]
Now run your service by pressing the “F5” in Visual Studio and open an “Internet Explorer” and open the created HTML file. Now the HTML code will contact the RESTful service and pass two values to the service (as a JSON object) and show the result value from server.

Easy, first WCF fully server and client

In this post I’m going to show how you easy steps to how you can create a server/client application base on WCF. Calling and receiving information from server to client and reverse. First of all create new solution called “ServiceHost”. Open Visual Studio 2010 and click on “File”->”New Project”:

And top section select “.Net Framework 4” and then from the “Installed Templates” select “Other Project Types” and then “Visual Studio Solutions”. On the right hand side select “Bank Solution”. Select the “Location” and solution name. Finally click on “OK”:

Now from the “File” menu click on “Add” and select “NewProject”:

From the list select “Class Library” and change the name to be “ServiceLibrary”:

 

From the solution explorer add a reference “System.ServiceModel” to the “ServiceLibrary” project.

Then:

 

From the “Solution Explorer” deleted automatically generated class file called “Class1.cs” and create new interface file called “ICalculator”:

 

Change the interface to become a public interface. Add extra using “System.ServiceModel” to the header, add “ServiceContract” attribute above the interface. Add new method called as below with “OperationContract” attribute.

Now create new class file called “Calculator”. Inherit the class from the “ICalculator” interface.

Now implement the interface as below:

 

From the menu “File”->”Add”->”New Project”, create a new console application project called “Server”:

And add the reference of “System.ServiceModel” to new created project called “Server”. Add another reference to “ServiceLibrary” project. Then build the project.

Now add new application configuration file to “Server” project.

Then:

Now build your project and you should get successful message from compiler. Now we need to configure the application to host the WCF service. So we need to change the app.config file first and introduce the service and configure it properly. For doing that open the “app.config” and change it to be like this:

 

This is the time for setting up your server runner. Open the “Solution Explorer”->”Server”->”Program.cs” and change it as below:

 

If you are using “Windows 7” or “Windows VISTA” when you want to start the application it may show you this message:

You can check the resolution here or easily run the “cmd.exe” in administrator mode and replace the command below and change the computer name and current user:

“netsh http add urlacl url=http://+:8082/ user={Computer Name}\{Current User}”

Now sever is ready and it is a time for building the client application. Add new “Console Application” project to your solution called “Client”. Then we need to add the reference of “Server” service to “Client” application. For doing that first run the server “Console Application” and make sure that service is running properly. For checking the server open an IE and change the address to http://localhost:8082 and should get the message as below:

 

After making sure that the service is working perfectly, for adding the “Service Reference” to “Client” application, right click on “Client” project and select “Add Service Reference”.

Submit the http://localhost:8082 to the address field and press the “Go” button”:

Then change the “Namespace” to “CalculatorClient” and press the “OK” button. Then open the “Client”->”Program.cs” and change it as below:

Make sure that the “Server” is running and then run the “Client”. You can the result as below:

 

You can download the sample from here