EPiServer 7 CMS – Custom Content

Jätä kommentti

https://www.dropbox.com/s/ivj147exezb546k/EPiServerCMSCustomContentProperty.zip

EPiServer CMS – Custom property to handle custom content. Lists all the custom content under current page and offers tools to create new content and edit and delete old ones.

EpiServer 7, managing custom contents

Jätä kommentti

This is my first blog about EpiServer. The problem is that I’m not familiar with all the terms used in EpiServer world and especially when talking about EpiServer 7 CMS. I’m not even sure if ”custom content” is the correct term or should I write about IContent. Anyway, here’s tiny, ugly piece of code I wrote to manage custom content in EpiServer’s edit view.

Basic problem was that Epi7 doesn’t have editor for custom content. Well, there is an editor to edit single custom content’s properties but there’s no way out-of-the-box to create or delete custom content objects.

I’m using MVC framework here so code contains normal Epi elements and MVC style controller and view. Code is, like I said, very ugly but it’s working. I’m just too lazy to refactor and clean it up. I placed the code in my dropbox shared folder.

https://www.dropbox.com/sh/jesqrdrx44lrrmr/Bi_PyalN5e/EpiTest.zip

In order to use the thing you need to create a single CustomContentPage type page anywhere in the system. This page should not be shown to the end user. It should be restricted for administrative use only.

Interesting parts of the code are:

Controllers\CustomContentController

This handles all the actions needed to list custom content anywhere on the site and contains methods to create and delete them. Take notice of heavy use of reflection. I just love .NET’s reflection.

Initializers\ContentTypeInitializer

Custom content needs to be registered to EpiServer. Here I initialize my ”BarContent”. BarContent implements IContent interface.

Initializers\RouteInitializer

Here I just register routes for AJAX calls. Nothing fancy.

Models\Pages\CustomContentPage

This is just a empty page type. This is needed because I implemented the editor as page in Epi’s page tree. I didn’t have time to find out how plugins are used in Epi7.

Models\ViewModels\CustomContentViewModel

View model object to store information passed between controller and view. The extension class in this file is particularly ugly but I was too lazy to find out how to do recursions in view.

View\CustomContentView

This is the view part of all this. First there is some jQuery stuff to handle button actions on client-side. Then some inline CSS because I was too lazy to write separate CSS file. Next there’s dialog template used when creating new custom content object and finally list view of all the custom content types and objects in the system.

Have fun.

Dynamics and JSON in C#

1 kommentti

I’ve been struggling to find anything useful usage for dynamics in C# and now at last I found something somewhat plausible. I was parsing JSON from Jira’s REST API for a little project of mine. First I thought that I convert JSON to XML – which is much easier to understand, at least to me – but then I got it! I use dynamics and a little helper class.

And because its been a while since I’ve blogged anything related to programming I thought I share my little helper class to all of you. So here it is.

using System;
 using System.Collections.Generic;
 using System.Dynamic;
 using System.IO;
 using System.Linq;
 using System.Web;
 using System.Web.Script.Serialization;

 namespace Weicco.Lib
 {
     public static class JsonParser
     {
         public static JsonObject Load(string filename)
         {
             var ser = new JavaScriptSerializer();
             return new JsonObject(ser.Deserialize<object>(File.ReadAllText(filename)));
         }
        public static JsonObject Parse(string json)
         {
             var ser = new JavaScriptSerializer();
             return new JsonObject(ser.Deserialize<object>(json));
         }
     }

     public class JsonObject : DynamicObject
     {
         private object o;

         public JsonObject(object o)
         {
             this.o = o;
         }

         public T GetValue<T>()
         {
             return (T)o;
         }

         public override bool TryGetMember(GetMemberBinder binder, out object result)
         {
             result = null;
             if (o is Dictionary<string, object>)
             {
                 var dict = o as IDictionary<string, object>;
                 if (dict.ContainsKey(binder.Name))
                 {
                     result = new JsonObject(dict[binder.Name]);
                 }
                 else
                 {
                     return false;
                 }
            }
             else
             {
                 var prop = o.GetType().GetProperty(binder.Name);
                 if (prop != null)
                 {
                     result = new JsonObject(prop.GetValue(o));
                 }
                 else
                 {
                     return false;
                 }
             }
            return true;
         }

         public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
         {
             result = null;

             if (o is Dictionary<string, object>)
             {
                 var dict = o as IDictionary<string, object>;
                 var key = indexes[0] as string;
                 if (dict.ContainsKey(key))
                 {
                     result = new JsonObject(dict[key]);
                 }
                 else
                 {
                     return false;
                 }
             }
             else if (o is object[])
             {
                 var key = (int)indexes[0];
                 var array = (object[])o;
                 if (key < array.Count())
                 {
                     result = new JsonObject(array[key]);
                 }
                 else
                 {
                     return false;
                 }
             }
             else
             {
                 var key = indexes[0] as string;
                 var prop = o.GetType().GetProperty(key);
                 if (prop != null)
                 {
                     result = new JsonObject(prop.GetValue(o));
                 }
                 else
                 {
                     return false;
                 }
             }

             return true;
         }
     }
 }

And here’s how you use it.

            dynamic json = Weicco.Lib.JsonParser.Parse(@"{""menu"": {
    ""id"": ""file"",
    ""value"": ""File"",
    ""popup"": {
        ""menuitem"": [
          {""value"": ""New"", ""onclick"": ""CreateNewDoc()""},
          {""value"": ""Open"", ""onclick"": ""OpenDoc()""},
          {""value"": ""Close"", ""onclick"": ""CloseDoc()""}
        ]
    }
}}");
            var id = json.menu.id.GetValue<string>();
            var menuItemOpen = json.menu.popup.menuitem[1].onclick.GetValue<string>();

A little thing about procedures and parameters

3 kommenttia

I though to blog about this although I’m sure there’s plenty of articles about this. In fact, I’m not going to argue my point at all. I’ll leave it up to reader to google this.

I’ve stumbled into a procedure which has ”dynamic” parameters. I mean parameters that are used in SELECT queries if they aren’t NULL. Here’s a simplified example of what I’m talking about.

CREATE PROCEDURE ExampleBad(@p1 int, @p2 int)
AS
BEGIN
    SELECT *
    FROM Foo
    WHERE
        (@p1 IS NULL OR Foo.p1 = @p1) AND
        (@p2 IS NULL OR Foo.p2 = @p2)
END

Now this looks nice and correct but SQL isn’t short-circuiting language. Meaning that even if @p1 was NULL, the condition of Foo.p1=@p1 is still evaluated. This leads to unnecessary evaluations. This leads also to a situation where query optimizer is unable to build correct query plan and statistics for the procedure, which is in 99,9% of cases a very bad thing.

Now here’s how it should be done. Dynamic SQL!

CREATE PROCEDURE ExampleGood(@p1 int, @p2 int)
AS
BEGIN
    DECLARE @sql NVARCHAR(MAX)
    DECLARE @params NVARCHAR(MAX)

    SET @params = N'@p1 int, @p2 int'
    SET @sql = N'SELECT * FROM Foo WHERE 1=1 '

    IF NOT @p1 IS NULL SET @sql = @sql + N'AND Foo.p1 = @p1 '
    IF NOT @p2 IS NULL SET @sql = @sql + N'AND Foo.p2 = @p2 '

    EXEC sp_executesql @sql, @params, @p1, @p2
END

HEDELMÄKAKKU

3 kommenttia

HEDELMÄKAKKU
 

1 dl VOITA
2 dl SOKERIA
4 MUNAA
2 dl KUIVATTUJA HEDELMIÄ
1 tl SUOLAA
1 dl FARIINISOKERIA
4 rkl SITRUUNAMEHUA

PÄHKINÖITÄ
2 l KONJAKKIA

Ota esiin suurehko kulho

Tarkista maistamalla konjakin laatu.
Kaada mittaan 1 dl konjakkia ja juo se. Toista.

Laita sähkövatkain päälle. Maista konjakkia uudelleen
varmistaaksesi, että se on korkealaatuista. Sekoita 1 dl voita laajassa sameahkossa kulhossa.

Lisää 1 rkl sokeria ja vatkaa taas.

Varmista, että konjakki on vielä hyvää. Kuo uusi jupillinen.
Käännä vatkaaja poish päältä.

Riko kaksi kanaa ja lishää kulhoon shamoin kuihvatut hedelmät.
Vatkaa kääntäjä taash päälle.

Jos heivatut kudelmat jäävät kiinni kulhoon, väännä irti
muuvireisselillä. Maishta shitten onko konjakki vielä
herkeälaatuishta.

Shitten shiivilöi 2 dl shuolaa, tai jotain. EI OO nii nöpönuukkaa.
Tshekkaa konhjakki.

Shiivilöi shitruunamehu, lishää yksi ruoka. Lushikka.
Shokeria tai jotain, AIVAN SHAMA PERKELE.

Voitele uuni. Käännä kakkuvuokaa 220 asteeseen. Älä unohda käännyttää
vatkainta poish. Heitä kulho ikkunashta, tsh..
tsehkkaahh taash konhjakki.
Mee nukkumaa. Kuka saatana ylipäätään viittii väshätä jotain pershkeleen hhetelmäkakkua?!

Installing SQL Server tools

1 kommentti

This is weird! I really can’t understand why installation of SQL Server and its components are this hard.
 
I got a new laptop. As a developer the first thing I did was to install Visual Studio 2008 so I could quickly continue my projects. It installed Sql Server 2005 Express to my computer. Everything works fine until…
 
Today I had to install Business Intelligense components and Sql Server Management Studio (2005 versions). I tried and tried to install those but the setup program kept telling me that I already have those components installed so it can’t install them. I was astonished at first, frustrated next, raving lunatic at last. I freaking do not have those components!
 
Then I suddenly realized! Sql Server 2005 Express is conflicting with the installation, even though it doesn’t contain Business Intelligense or Management Studio. I uninstalled it and finally was able to install what I needed.
 
Why on earth SSMS is not its own installation package? Why Business Intelligense tools aren’t separate installation package? Why the heck is Sql Server 2005 Express conflicting with these? – Just some question that went throught my mind today.

Lokalisoinnin ihmeitä

Jätä kommentti

Olenko kertonut kuinka paljon tykkään lokalisoiduista käyttöliittymistä? Tässä esimerkki joka kirvoitti hymyn kasvoille.
 
 
Taidanpa alkaa virtauttamaan itseäni kahville…

Vanhemmat artikkelit

Seuraa

Get every new post delivered to your Inbox.