XForm is a somewhat of a lazy way out. You know you should do the forms yourself but XForm is simple for the editors and also saves you a lot of job. Anyway, if you want to use XForm to make a poll, you’ll need to make a few adjustments.

First:
Create your new control and add an XForm property to the controls pagetype

Second:
Here you can take the template code from EPiServer to get the basic XForm functions.

Third:
Create your XForm in EPiServer and assign it to your page. Make sure to let anonymous post and also multiple times (Because all your users will be anonymous and you want anonymous to be able to vote more than once)

Fourth:
Create a cookie so people only vote once (they can delete their cookies and vote over and over so if you want a more secure way, go ahead and do it =D) and also so you can display the results insetad of the poll whenever they visit the page again.

The cookie could look something like this:
[sourcecode lang=”c#”]
private void SetCookie()
{
var cookie = new HttpCookie(”Poll-” + page.PageLink.ID);
cookie.Values.Add(”voted”, ”true”);
cookie.Expires = DateTime.Now.AddYears(24);
Response.Cookies.Add(cookie);
}
[/sourcecode]
and then you can check for the cookie and give the user different views depending if they voted or not. And that code could look something like this
[sourcecode lang=”c#”]
return;
var cookie = Request.Cookies.Get(”Poll-” + page.PageLink.ID);
if (cookie== null)
SetupForm();
else
SwitchView(null,null);
[/sourcecode]
Fifth:
If you’re using your XForm directly on a page, then you probably don’t need this step and you’re pretty much set. But if you want to use this as a usercontrol and add the poll with webparts or anything alike you’ll need to do this step.

The thing with EPiServers Statistics is that it will always fetch ”this.PageLink” so if you’re using this as a webpart/control it will try to get the currentpages xform property which will be null. Even if you load the XForm correctly and fetch it from your usercontrol path, the statistics won’t do it. In order to make Statistics work you’ll have to do this:
[sourcecode lang=”c#”]
Statistics.PageLink = page.PageLink;
Statistics.PageGuid = Form.PageGuid;
[/sourcecode]
Otherwise it will take the currentpage pagelink and pageguid. So basicly, you need to set up the Statistics just as you need to set up XForms.

Good luck!

Huge title but pretty much what this post is about.

To optimize your FindPagesWithCriteria, it’s good to be as specific as you can. i.e not use one criteria, get 500 hits back and then just use the top 5 out of those. Anyway, when using a PropertyDataType.Boolean and you want to get back those pages that has this set to ”false” you can’t really set the value to ”false”. Why? Because when the property is false, it has never been set which makes it null.

Let’s see the code:
[sourcecode lang=”c#”]
PropertyCriteria crit = new PropertyCriteria{
Condition = CompareCondition.Equal,
Name = ContentPropertyStrings.Finished,
Type = PropertyDataType.Boolean,
Value = ”false”,
Required = true
};
[/sourcecode]

The code above won’t give you any hits since there won’t be any property set to false, because those properties are null. What you need to do is what you can see below.

[sourcecode lang=”c#”]
PropertyCriteria crit = new PropertyCriteria{
Condition = CompareCondition.Equal,
Name = ContentPropertyStrings.Finished,
Type = PropertyDataType.Boolean,
IsNull = true,
Required = true
};
[/sourcecode]

An old problem but I still get this question from time to time so might aswell post it 🙂

When you want to alter a page programmatically you need to use EPiServers CreateWriteableClone on the working page. This is because the Page itself is readonly. Now, there’s plenty of info out there how to do this, but just to refresh your mind, here’s some code:
[sourcecode language=’c#’]
PageData clone = pd.CreateWritableClone();
clone.Property[”MyProperty”] = ”New value”;
DataFactory.Instance.Save(clone, SaveAction.Publish);
[/sourcecode]

Simple enough, right?

Now, here’s the catch. If you are for example saving page ID’s into a customproperty, simply like this ”42 43 553 23” and so forth and you want to change this programmatically by removing one and adding one. So for example, going from ”42 43 553 23” to ”42 43 55” won’t work with the code above. The result will be ”42 43 553 23 55” as it will only add it up to your current value. So you want to clear your value before you set it although that is also not enough. You’ll have to save the page after you clear it and THEN you can set your new value and save the page. Something like this

[sourcecode language=’c#’]
PageData clone = pd.CreateWritableClone();
clone.Property[”MyProperty”].Clear();
DataFactory.Instance.Save(clone, SaveAction.Publish);
clone.Property[”MyProperty”] = ”New value”;
DataFactory.Instance.Save(clone, SaveAction.Publish);
[/sourcecode]

If someone has a better way to override values without having to doublesave, please do let me know.

FindPagesWithCriteria is a very handy way to pick up pages that are spread out around your site but there’s a tiny thing that is good to remember when using FindPagesWithCriteria to find pages based on a CustomProperites that you’ve made. Never ever forget to click ”searchable property”  when you add the customproperty to your page. Why? Because if this is not checked, FindPagesWithCriteria won’t be able to find it, simple 🙂

Tiny post for a tiny problem that can cause a lot of headache 😉

HTML 5 introduces new elements to use such as <header> <section> <nav> and many more. The problem is that no version of Internet Explorer recognizes the new elements, but Firefox, chrome and many others does. The solution is easy but a bit boring when you think about it, since it’s about replacing all new elements to div instead. Which means that IE users won’t be able to appreciate HTML5 but users that use Firefox, Chrome and so on will.

Anyway, on with the solution! What you need to do is modify the writer and basically find all elements and change them with a div.  A good place to do it on is on your masterpage.

[sourcecode language=’c#’]
protected override void Render(HtmlTextWriter writer)
{
if(Request.Browser.Browser == ”IE”)
HTML5Replace(writer);
else
base.Render(writer);
}

private void HTML5Replace(HtmlTextWriter writer)
{
MemoryStream memoryStream = new MemoryStream();
StreamWriter streamWriter = new StreamWriter(memoryStream);
HtmlTextWriter memoryWriter = new HtmlTextWriter(streamWriter);
base.Render(memoryWriter);
memoryWriter.Flush();
memoryStream.Position = 0;
TextReader reader = new StreamReader(memoryStream);
string output = reader.ReadToEnd();
output = Regex.Replace(output, RegExStrings.HTML5_BLOCK_ELEMENTS , RegExStrings.HTML5_BLOCK_ELEMENTS_REPLACEMENT );
writer.Write(output);
}

[/sourcecode]

But what REALLY does the magic is the RegEx, since it will find the elements for you and replace them correctly.

[sourcecode language=’c#’]
public const string HTML5_BLOCK_ELEMENTS = @”<(\/)?(nav|section|header|aside|footer)"; public const string HTML5_BLOCK_ELEMENTS_REPLACEMENT = @"<$1div"; [/sourcecode] The reason why I use $1 on the replacement string, is because I want to add a "/" if there is one in the element I found. This to close the tag correctly. So basically, when it finds "<nav" it will replace it with "<div" and when it finds "</nav" it will replace it with "</div". Closing tag and class/id names will still be there so the div can take on the behavior of the replaced element. Another problem that you will run into, if you're running your site with EPiServer that is, is that EPiServers friendlyurlrewriter doesn't recognize the doctype and it will try to fix it for you. For HTML 5 you'll need the following doctype  "<!DOCTYPE html>" but EPiServer will change it to the following "<!DOCTYPE HTML PUBLIC "" "">". Mohsen Pirouzfar found a great solution for this which you can read here. It’s in swedish but the code itself is usable to anyone 🙂

After upgrading EPiServer CMS5 r2 to CMS5 r2sp2 you might get a nice little error in edit mode. This page is not available for the active language. This is due globalization changes and the workaround is to activate a language for your site. To do this do the following:

1. Go to admin mode
2. Click on Config
3. Go to systemsettings
4. Activate Globalization
5. Go to Edit mode
6. click on Language Settings
7. Chose the default language
8. Go back to admin mode
9. Turn off globalization

This should do the trick. Remeber, if you have several sites, you need to click on the root of each one of them and set the language settings on all of them.

Using EPiServers softlink can really come in handy in different situations.  Mostly of course when you need to gather information from the linked pages of a document.

Here’s an example on how to use this:

Example in VB.Net

[sourcecode language=’vb.net’]

Dim f As EPiServer.Web.Hosting.UnifiedFile = TryCast(System.Web.Hosting.HostingEnvironment.VirtualPathProvider.GetFile(filename), EPiServer.Web.Hosting.UnifiedFile)

Dim filecollection As EPiServer.DataAbstraction.SoftLinkCollection = EPiServer.DataAbstraction.SoftLink.Load(f)

For Each file As EPiServer.DataAbstraction.SoftLink In filecollection
Dim ref As New PageReference
ref = file.OwnerPageLink
’now you can work your magic
Next

[/sourcecode]

Example in C#:

[sourcecode language=’c#’]

EPiServer.Web.Hosting.UnifiedFile f = System.Web.Hosting.HostingEnvironment.VirtualPathProvider.GetFile(filename) as EPiServer.Web.Hosting.UnifiedFile;

EPiServer.DataAbstraction.SoftLinkCollection filecollection = EPiServer.DataAbstraction.SoftLink.Load(f);

foreach (EPiServer.DataAbstraction.SoftLink file in filecollection) {
PageReference ref = new PageReference();
ref = file.OwnerPageLink;
//now you can work your magic
}

[/sourcecode]

So what you need to do is pretty much to load up the file reference into a softlink and fill a softlinkcollection with that. Then just run a for each on the collection (since a document can have several linking pages). Once you get your reference, you can just do a getpage on the ref and grab whatever you need from the linking page.

One of our customers found a little annoying bug when publishing news to their page.

The bug goes as following:

News page type contains a few categories as well as an extra date field to point out the news date (in case you don’t want to use the publishing date and want to use your own) and it’s required as well.

You forget to fill out the news date,  but fill everything else up, including choosing which categories the news should belong too and then hit Save and Publish.

EPiServer will do a postback and warn you about not filling in the news date. If you at this moment check the categories, you’ll see that they are still clicked in, you fill in the date and hit save and publish once more.

The news will be posted but without the categories as EPiServer will lose the values on the postback but still show them as checked.

This is a verified bug from EPiServer and hopefully to be fixed in an upcoming version.

This error happens after a migration to EPiServer CMS 5 r2 when you try to change the password of a user or possibly create a user. The error is very missleading and has nothing to do at all with the role nor membershipprovider. The error is actually a very simple one.

Another user is using the email that you are providing or your user does not have an email at the moment.

All you need to do is either delete one of the users or change the mail adress of one of the users in order to ”lock them up” and be able to change the password.

So during an upgrade to EPiServer 5, I ran into this problem where the culture was wrong and all translations were being translated to English instead of Swedish, this even though the web.config was correctly changed to ”sv-SE”.

After som trial and error I got to set the culture in onpreinit in the a class that inherits templatepage like this

EPiServer.Globalization.UserInterfaceLanguage.Instance.SetCulture(”sv-SE”)
EPiServer.Globalization.SystemLanguage.Instance.SetCulture(”sv-SE”)

The problem was that only the dates were being formatted correctly, but the translation was still wrong. CurrentPage.LanguageID was not of much help either as it was set to english. At last I found out that you just need to send the short version of the culture to make it work. i.e

EPiServer.Globalization.UserInterfaceLanguage.Instance.SetCulture(”SV”)
EPiServer.Globalization.SystemLanguage.Instance.SetCulture(”SV”)

This did the trick and now everything is in the right format.