TinyMCE in an EPiServer template page

In this project I’m working in at the moment we are developing an intranet based on EPiServer Relate. Currently in phase 2 of the development we are going to add the possibility for the users to blog about work etc on the intranet. If you look at the blog template in the Relate templates it’s kind of stripped of the possibilities to format the entered text etc. Nowadays EPiServer comes with TinyMCE so we placed an editor in the page with the following initialization:

tinyMCE.init({
mode: "specific_textareas",
editor_selector:"entryEditor",
theme: "advanced",
skin:"epi-light",
plugins:"epilink,table,media,advimage,epifilebrowser,paste",
theme_advanced_toolbar_location: "top",
theme_advanced_toolbar_align: "left",
theme_advanced_statausbar_location: "bottom",
theme_advanced_buttons1: "epilink,unlink,separator,image,media,separator,cut,copy,paste,pastetext,separator,tablecontrols",
theme_advanced_buttons2: "bold,italic,underline,separator,justifyleft,justifycenter,justifyright,separator,bullist,numlist,hr,separator,formatselect,separator,styleselect,separator,visualaid,fullscreen",
theme_advanced_buttons3:"",
theme_advanced_resizing: true,
content_css: "tinymce.css,editor.css",
theme_advanced_blockformats: "p,h2,h3",
width: '448',
height: '400'
})

which is a pretty standard editor and gives us an editor looking like this:

TinyMCE editor

There are a couple of EPiServer specific plugins added epilink and epifilebrowser. Epilink makes it possible for the user to create links to pages with the help of EPiServer page browser. Epifilebrowser on the other hand handles the functionality that inspired my to write this post, since that was the thing I couldn’t find out how to do.

Epifilebrowser is a non-visual TinyMCE plugin that adds a button in for example the image popup so you can use the EPiServer file browser for choosing your images.

Filebrowser button in image popup

The problem after this is that now we want to get the imagegallery of the blog to show up in the file browser, and I’ll come back to that when I have got the virtualpathprovider for that up and running.

Posted in CMS, Community, EPiServer, Tips | Tagged , | Comments Off on TinyMCE in an EPiServer template page

WordPress admin in EPiServer Online Center

This was just made as a demo where I wanted to show how to have the admins of two systems in the same when having EPiServer as main CMS. It’s the same approach as EPiServer themselves has with their EPiServer Commerce module.

What I did was implementing a simple case of integrating the admin of WordPress into EPiServers Online Center.

First we will need a menuprovider to get the menu buttons into the Online Center. This is very straight forward since EPiServer provides the base for this with the MenuProviderAttribute and IMenuProvider interface, more about how to extend the navigation in Online Center.

[MenuProvider]
    public class WordpressMenuProvider : IMenuProvider
    {
        public IEnumerable<MenuItem> GetMenuItems()
        {
            var section = new SectionMenuItem("Wordpress", "/global/wordpress")
                              {IsAvailable =request => PrincipalInfo.HasEditAccess};
 
            var wordpressAdmin = new UrlMenuItem("Admin Mode", "/global/wordpress/admin", "/Views/Shell/Admin/Default.aspx")
                                 {IsAvailable = request => PrincipalInfo.HasAdminAccess,SortIndex = 10};
 
            var wordpressSettings = new UrlMenuItem("Settings", "/global/wordpress/settings", "/Views/Shell/Admin/Settings.aspx") { IsAvailable = request => PrincipalInfo.HasAdminAccess, SortIndex = 10 };
 
 
            return new MenuItem[] {section,wordpressAdmin,wordpressSettings};
        }
    }

As you see in the constructor of the UrlMenuItem there is XPath, for example “/global/Wordpress” as our menu root, present and that is where the menu buttons will appear. After building this you shold have something looking like this:

The menu for WordPress consists of two choices, Admin and Settings. The settings page is just for setting up where the WordPress admin is located on the web, which I put into the following class:

using EPiServer.PlugIn;
 
namespace Barely.EPi.Beta.AddOn.Wordpress.Shell
{
public class WordpressSettings
    {
        [PlugInProperty(Description = "Sets the URL for the Wordpress admin", DisplayName = "WordpressAdmin")]
        public string WordpressAdmin { get; set; }
 
        [PlugInProperty(Description = "Which pagetype to use for Wordpress blog posts",
            DisplayName = "WordpressPostPageType")]
        public string WordpressPostPageType { get; set; }
 
    }
}

The both admin pages has the same base class since they both need access to the settings so this is the WordPressAdminPageBase:

using System;
using System.Data;
using EPiServer;
using EPiServer.PlugIn;
using EPiServer.Shell;
using EPiServer.UI;
 
public class WordpressAdminPageBase: SystemPageBase
    {
        public WordpressAdminPageBase() : base()
        {
        }
 
        public WordpressAdminPageBase(int enable,int disable):base(enable,disable)
        {
        }
 
        public WordpressAdminPageBase(int options) : base(options)
        {
        }
 
        public string WordpressAdmin
        {
            get
            {
                string ret = null;
 
                var ds = new DataSet();
                var dt = ds.Tables.Add("dt1");
                dt.Columns.Add("wordpressadmin");
 
                PlugInSettings.Populate(typeof(WordpressSettings), ds);
 
                if (ds.Tables.Count == 1)
                {
                    if (ds.Tables[0].Rows.Count > 0)
                        ret = ds.Tables[0].Rows[0][0] as string;
                }
 
                return ret;
            }
 
protected override void OnPreInit(EventArgs e)
        {
            base.OnPreInit(e);
 
            MasterPageFile = Paths.ToShellResource("Views/Shared/Site.master");
        }
 
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            RegisterClientScriptFile(UriSupport.ResolveUrlFromUIBySettings("javascript/system.aspx"));
        }
 
 
        }
    }

The aspx for the settings page look like this:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Settings.aspx.cs" Inherits="Barely.EPi.Beta.Web.Views.Shell.Admin.Settings" %>
<%@ Register TagPrefix="EPiServerUI" Namespace="EPiServer.UI.WebControls" assembly="EPiServer.UI" %>
<asp:content runat="server" ContentPlaceHolderID="MainContent">
<form runat="server">
<label for="WordpressAdminUrl">URL for Wordpress admin</label><asp:textbox runat="server" id="WordpressAdminUrl" /><br />
<EPiServerUI:ToolButton ID="saveChanges" OnClick="SaveSettings" Text=" Save " runat="server" />
</form>

And the code behind:

using System.Data;
using EPiServer.PlugIn;
using EPiServer.UI;
 
namespace Barely.EPi.Beta.AddOn.Wordpress.Shell
{
public partial class Settings : WordpressAdminPageBase
    {
 
        public Settings()
            : base(0, LoadCurrentPage.OptionFlag)
        {
        }
 
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (IsPostBack)
                return;
 
            WordpressAdminUrl.Text = WordpressAdmin;
 
        }
 
        protected void SaveSettings(object sender, EventArgs e)
        {
            var ds = new DataSet();
            var dt = ds.Tables.Add("dt1");
            dt.Columns.Add("wordpressadmin");
 
            var dr = dt.NewRow();
            dr[0] = WordpressAdminUrl.Text;
            dt.Rows.Add(dr);
 
            PlugInSettings.Save(typeof(WordpressSettings), ds);
        }
 
    }
}

Now we get a page looking like this, with some unmentioned addons, they are a future post.

Now you can set the where the user will end up when clicking on the Admin menu item, but before you can do that we’ll have to make the Admin-page. I did this by just using an iframe and populate it’s source with the provided URL.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Barely.EPi.Beta.Web.Views.Shell.Admin.Default" %>
<asp:content runat="server" ContentPlaceHolderID="MainContent">
<iframe src="<%= WordpressAdmin %>" height="100%" width="100%"/>
</asp:content>

With the following code behind:

using System;
using Barely.EPi.Beta.AddOn.Wordpress.Shell;
using EPiServer;
using EPiServer.Shell;
using EPiServer.Web.PageExtensions;
 
namespace Barely.EPi.Beta.Web.Views.Shell.Admin
{
    public partial class Default : WordpressAdminPageBase
    {
 
 
        public Default():base(0,LoadCurrentPage.OptionFlag)
        {
        }
 
 
    }
}

Now when you click the Admin menu item you should get something that looks like this:

Now you have portal to your WordPress site via EPiServer.

Source code »

Posted in EPiServer, Software development | Tagged , , , | Comments Off on WordPress admin in EPiServer Online Center

Problems with adding Community to existing EPiServer CMS site

At the assignment I’m at right now we’re building a intranet based on EPiServer. We started out with just the CMS because the customer wanted to think through if they would go full monty and get Relate+. Now they’re done thinking and yes add Community to the CMS. That should be easy, there’s an option for that in Deployment Center. It wasn’t… But that wasn’t EPiServer’s fault =)

The problem was that when the Deployment Center tried to run the sql script for installing the database stuff for EPiServer Community we got the error message “There is insufficient system memory in resource pool ‘internal’ to runt this query”. After a couple of hours of trying to figuring out why, and googleling a lot, I came to the conclusion that something must be wrong with the database. The Sql Server wasn’t updated with any service packs so guess what gave us a solution to the problem…? Adding Service Pack 2 to the Sql Server 2008. The option could be adding just some hotfixes if you don’t want to add the Service Pack. But as being an old IT-technician I always add an service pack rather than just a hotfix included in the service pack

Now we only have the problem that the Community tab isn’t showing in Online Center, but I guess that’s a question of configurating EPiServer the right way… TGIF =)

Posted in CMS, Community, EPiServer, Tips | Tagged , , , , | Comments Off on Problems with adding Community to existing EPiServer CMS site

IE8 and compability problems with Intranet Zone

The different looks in local and test machineI have been having this problem at a customer that the site on my developing machine it looked good when the site was rendered, but then when I moved everything to the test server it didn’t look quite the same.

I had had the same problem when I moved the source from my laptop to the developing machine, but then the solution was not the same as the one I finally found. The solution wasn’t that obvious and Google had the solution… The problem was that in an Intranet Zone IE8 is set to use the compability mode, ie render the pages as IE7. It all came clear to me when I found this blog post of Raj Kaimal.

The organization I’m at the moment has a very rigid IT-support so the solution wasn’t to make them change the settings. I just did as it’s said in this article at MSDN, but I set the HTTP Custom Response Header “X-UA-Compatible” to “IE=100″, ie IE8.

Problem solved…

Posted in Browser, IIS, Tech, Tips | Tagged , , , | Comments Off on IE8 and compability problems with Intranet Zone

Easy fix for Android update com.android.browser

After the update to Froyo on my HTC Desire I got the common problem with com.android.browser wanting to force close every time I tried to use the Internet app. By mistake I found and easier solution than hard resetting the phone.
Under Settings/Application/Manage applications you have a tab saying All. Under that tab you’ll find the Internet app. Click on it and you’ll find a button called Clear data. I don’t know what kind of data you lose but now I don’t get the force close message at  least. I didn’t have to backup everything, doing a hard reset and performing the update again.

Posted in Android, Tips, Tricks | Tagged , , , , , | 6 Comments

Instance validation error exporting page types from migrated EPiServer

I’ve been sitting the last couple of days migrating a site for a customer just for them to test the new site with live data and it has been a struggle. The last obstacle has been that when I wanted to migrate the page types from the developing site’s database I got an error saying “Exception: There was an error generating the XML document.[Instance validation error: ‘268435455’ is not a valid value for EPiServer.Editor.EditorToolOption.]”. Since Google and I still are really good friends a search for that error message got me one hit in EPiServer forums i went there and found the solution.

The solution is that you have to re-save all properties with the LongStringSetting value set to 268435455. I don’t know if there’s a way to the make this procedure with an application, but I did it by hand. Yeah, it took a while, but I got my exported data at least.

To get all these properties there is a SQL query in that thread which I modified a bit so I got the data sorted in a better way:

SELECT     tblPageDefinition.pkID, fkPageTypeID, tblPageType.Name, tblPageDefinition.Name, LongStringSettings
FROM         tblPageDefinition, tblPageType
WHERE tblPageType.pkID = tblPageDefinition.fkPageTypeID
ORDER BY LongStringSettings DESC,tblPageType.Name,tblPageDefinition.FieldOrder

One thing that I did discover though is that you have to do the same with your dynamic properties, if you are using them.

Posted in EPiServer, Software development | Tagged , , , | 1 Comment

Google Calendar API

At a previous blog of mine I wrote an article about having trouble with the fetching of items from Google Calendar with Google’s API for .Net. In post I’ll write this post in a different way.

I’m doing this site where we want to use the Google Calendar for the calendar function of the site. Now that seemed to be easy since Google as an API for .Net, but it wasn’t that easy. Now, why was that? I’ll explain why.

Firstly some of the parameters aren’t clearly explained how they are set in the objects. My main problem was that you can’t set a category to an event, even though you can grab a category property in the API. My solution to the problem was to fake a category in the header of the event and then search for those among the events I’d get.

Secondly I had a problem with that the web hotel where the site is published is in Denmark and they have apparently installed their servers with danish language settings and that caused the problem that the result from Google Calendar was presented in Danish instead of Swedish which I had wished for. The solution to this came when I started to read which parameters got set when I played around with generator of code to insert in a web page if you want the calendar presented in your own page. I then figured out which parameter I had to put in the query.ExtraParameters property, which was the “hl=sv”. Below you can see final and working code and the result of this can be view at web site of Fisksätra scout troop.

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
public AtomEntryCollection GetEvents(int count, string text)
        {
            EventQuery query = new EventQuery(feedUrl);
            query.TimeZone = "Europe/Stockholm";
 
            if (!string.IsNullOrEmpty(text))
            {
                query.Query = text;
                query.SingleEvents = true;
            }
 
 
            if (count >= 0)
                query.NumberToRetrieve = count;
            else
                query.NumberToRetrieve = int.MaxValue;
 
            query.SortOrder = CalendarSortOrder.ascending;
            query.ExtraParameters = "orderby=starttime&hl=sv";
            query.StartTime = DateTime.Now;
 
            EventFeed eventFeed;
            try
            {
                eventFeed = service.Query(query);
 
 
                return eventFeed.Entries;
            }
            catch (Exception e)
            {
                return null;
            }
 
        }
Posted in .Net, Google, Software development | Tagged , , | 1 Comment