Using TranslateX with EPiServer 6 R2

In a recent project, I had to install the TranslateX module into an EPiServer 6R2 site. TranslateX is an open source EPiServer module that allows you to export pages in XLIFF format for translation services. The problem is that the original module was created for EPiServer 4 and has been since updated to work with version 6.0, but I was unable to find any resources or help to get it installed in 6R2 or 7. After some trial and error, I came up with these steps.

  1. Download EPiServer CMS 6.0 from EPiServer World and install it. Don’t worry — even though it’s an older version, it shouldn’t cause any problems with your R2 installation.
  2. Download the install package for the 6.0 version of the module.
  3. Run EPiServer Deployment Center (located at C:\Program Files (x86)\EPiServer\Shared\Install\EPiServerInstall.exe by default).
  4. On the All Actions tab, run Installed Products > EPiServer CMS > Version 6.0.x > Modules > EPiServer.Research.TranslateX.Installer.6.
  5. The default options for the first step of the installer should be fine. On step 2, check the “Show All Sites” check box, and then select the site where you will install TranslateX. (Note: You will receive a compatibility warning when you check the “Show All Sites” check box, but it doesn’t appear to be a problem.)
  6. Finish the installation.

Now, you should have it successfully installed. However, there’s more to do before it’ll work. First, you will need to create a folder for TranslateX to save temporary files, and EPiServer will need write access to the folder. You can name the folder “translationtemp” or something similar.

Open your Web.config file and look in the AppSettings section for a key named “xliffworkpath”. You’ll need to update this value with the location of your “translationtemp” directory.

At this point, you can now create translation projects for your pages by navigating to a page in the CMS and clicking the “Translation” tab. But when you try to run the project (Admin Mode > Admin tab > Scheduled Jobs > Translation scheduler service > Start Manually), you’ll probably notice an error on the “History” tab and you will never receive an e-mail with the translation. That’s because you will need to tell EPiServer which languages are available for translation through an XML file.

In the root folder of your EPiServer installation, there should be a “lang” folder. Create an XML file called “translationlangs.xml” and place it in that folder. Here’s a sample of the content to include in the XML file:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<languages>
	<language name="English" id="en">
		<translationlanguages>
		<en>en</en>
		<en-GB>en-gb</en-GB>
		<es>es</es>
		</translationlanguages>
	</language>

	<language name="British" id="en-GB">
		<translationlanguages>
			<en>en</en>
			<en-GB>en-gb</en-GB>
			<es>es</es>
		</translationlanguages>
	</language>

	<language name="Spanish" id="es">
		<translationlanguages>
			<en>en</en>
			<en-GB>en-gb</en-GB>
			<es>es</es>
		</translationlanguages>
	</language>
</languages>

Make sure to update the XML to fit your own language needs. As long as your mail server is working, you shouldn’t need anything else. If the “History” tab on the translation scheduler service says, “OK,” after starting the service, you’re good to go.

I haven’t tried installing TranslateX in EPiServer 7, but let me know if the steps above were any help.

Strongly Typed Ektron Smart Forms

Unfortunately, Ektron still doesn’t allow for strongly typed access to smart forms out of the box. However, that doesn’t mean you’re stuck using XSLT or parsing the XML. Some time ago, Bill Cava hosted a webinar titled Ektron Content Types that explained how to gain strongly typed access to smart forms by serializing the XML into a .NET class. It’s a great webinar, but a few things were left out, so I figured I’d include some instruction in a little more detail (mainly for my own reference).

Step 1: Getting the Smart Form XSD

Assuming you’ve already created your smart form, the next step is to get its XSD, or XML Schema Definition. To do this, click the XSD icon in the smart form designer toolbar. Now, copy the content to a plain text file, and save it as MySchema.xsd (obviously, replace MySchema with something relevant to your smart form — this will become the .NET class name also).

Step 2: Creating the .NET Class from Your XSD

Visual Studio comes with an application called xsd.exe, which you can use to automatically generate your .NET class from the XSD. If you don’t have or can’t find xsd.exe, there are online services that can do this as well (e.g. http://www.bware.biz/DotNet/Tools/CodeXS/WebClient/GenerateInput.aspx). Assuming you’re using xsd.exe, let’s create a .bat file and add the following to it (if you aren’t familiar with batch files, just open Notepad, type the code below and save as xsd.bat):

SET ROOT=C:\"Program Files (x86)"\"Microsoft SDKs"\Windows\"v8.0A"\bin\"NETFX 4.0 Tools"\
SET XSDPATH=C:\Users\username\Desktop\
SET XSDFILE=%1
SET NAMESPACE=%2

%root%xsd %XSDPATH%%XSDFILE% /classes /language:CS /namespace:%NAMESPACE% /outputdir:%XSDPATH%

Make sure to update XSDPATH to the path where you saved your XSD file from the last step (or move your file to the desktop). Also the ROOT path may be different for you depending on where your xsd.exe is located. Update it accordingly.

Now, open a command prompt (Windows key + R, type cmd, and press Enter), type the following, and press Enter:

cd C:\Users\username\Desktop

Note: If you saved your xsd.bat file somewhere other than the desktop, cd into that directory instead of the above.

Now type the following, making sure to replace “MySchema.xsd” with the name of your XSD file and “Some.Namespace” with your own custom namespace:

xsd.bat MySchema.xsd Some.Namespace

After the commands from the batch file are done, you should have a new .cs file in the same folder as your XSD file.

Step 3: Update the .NET Class

Although xsd.exe creates your .NET class for you, there are some changes you’ll need to make that weren’t mentioned in the Ektron webinar. First, you’ll want to change the following, which should appear near the top of the .cs file:

[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
    public partial class root {
        ...
    }

to this:

[System.Xml.Serialization.XmlRootAttribute(Namespace="", ElementName="root", IsNullable=false)]
    public partial class MySchema {
        ...
    }

Notice that we added ElementName="root", and we changed the class name from “root” to one better fitting our class. If our smart form was named “Book,” for example, we’d have chosen “Book” for the name of the class.

Now move the .cs file to your website’s AppCode folder, or wherever it fits best in the architecture of your website.

Step 4: Using the ContentTypeManager<T> and ContentType<T> Classes

Download Ektron’s source code for the ContentTypeManager and ContentType classes, and copy the ContentType.cs file to your AppCode directory (or wherever applicable). The webinar does a good job of explaining how to use ContentTypeManager and ContentTypes, so I won’t go into detail with their usage. Here’s some sample code to get you started:

ASPX

<asp:Repeater ID="MyRepeater" runat="server">
    <ItemTemplate>
        <p><%# Eval("SmartForm.Property") %></p>
    </ItemTemplate>
</asp:Repeater>

ASPX.CS

long folderId = 32; // Folder containing our smart form content
ContentTypeManager<MySchema> mgr = new ContentTypeManager<MySchema>();
Criteria<ContentProperty> criteria = new Criteria<ContentProperty>();
criteria.AddFilter(ContentProperty.FolderId, CriteriaFilterOperator.EqualTo, folderId);
List<ContentType<MySchema>> items = mgr.GetList(criteria);

MyRepeater.DataSource = items;
MyRepeater.DataBind();

Step 5: Updating the .NET Class for Rich Text and Other Complex Types

Another problem, not mentioned in the webinar, that you’re likely to run into is rich text fields and other smart form data types that don’t map to a standard .NET type. I’ll explain how to handle rich text, and figuring out the others should be self explanatory afterward.

Basically, what happens is that your .NET class will contain new types for anything that it doesn’t understand (i.e. anything other than String, DateTime, Int32, etc.). One of these types is “rich”, which it creates for rich text boxes. Search for the following in your MySchema.cs file:

public partial class rich {
    ...
}

What we want is for the “rich” type to return a string representation of the nodes it contains. To do this, we need to override its ToString() method. Add the following directives at the top…

using System.Text;
using System.Xml;

and add the following after the “rich” class’s field declarations:

public override string ToString()
{
    StringBuilder sb = new StringBuilder();

    foreach (XmlNode item in this.anyField)
    {
        sb.Append(item.OuterXml);
    }

    return sb.ToString();
}

Use the same approach for other Ektron smart form types that don’t match up to a .NET type.

At this point, you should have everything you need. Enjoy!

Using Magento CE on Go Daddy Shared Hosting

I recently installed Magento Community Edition on a Go Daddy shared Linux server, and I ran into a few problems that I thought I would share in case anyone else has the same issues.

Making the Installation Work

After uploading all the files, the first problem you may run into is that the installation wizard doesn’t work. Instead you get a blank page with the words “No input file specified.” You will need to make a couple changes to your .htaccess and php.ini files to get past this.

First, uncomment line 12 of .htaccess (remove the #). It should look as follows:

############################################
## GoDaddy specific options

Options -MultiViews

## you might also need to add this line to php.ini
##     cgi.fix_pathinfo = 1
## if it still doesn't work, rename php.ini to php5.ini

Next, rename the php.ini.sample file to php5.ini, open it, and add the following to a new line at the very end (as suggested in the .htaccess file ):

cgi.fix_pathinfo = 1

Upload these two files, but hold on — there is still one more step before you can install. Log into your Go Daddy hosting control panel, and click the “File Extensions Management” icon in the “Settings” section. You will need to change the .php and .php5 extensions to run under PHP 5.2.x (not the FastCGI option).

Go Daddy file extensions menu

After these changes, you shouldn’t have any problems getting through the installer. However, if you’ll be using Go Daddy’s preview DNS feature to view your website before changing DNS records, there are a few more things you need to do.

Using Go Daddy’s Preview DNS Feature with Magento

During the installation, you will be asked for your site’s “Base URL.” Enter http://yoursite.com.previewdns.com/ (or whatever your preview DNS URL happens to look like). Installation should finish without problem, but when you try to log into the admin panel, you’ll see that it’s a no-go. No error, no warning, nothing — it will simply show the login dialog again. This has to do with how Magento sets cookies for the admin panel, and to fix it, we need to temporarily comment out some code. Open the file at /app/code/core/Mage/Core/Model/Session/Abstract/Varien.php. Around line 94, you should see the following:

if (!$cookieParams['httponly']) {
    unset($cookieParams['httponly']);
    if (!$cookieParams['secure']) {
        unset($cookieParams['secure']);
        if (!$cookieParams['domain']) {
            unset($cookieParams['domain']);
        }
    }
}

if (isset($cookieParams['domain'])) {
    $cookieParams['domain'] = $cookie->getDomain();
}

Comment out this section, save the file, and upload it.

/*
if (!$cookieParams['httponly']) {
    unset($cookieParams['httponly']);
    if (!$cookieParams['secure']) {
        unset($cookieParams['secure']);
        if (!$cookieParams['domain']) {
            unset($cookieParams['domain']);
        }
    }
}

if (isset($cookieParams['domain'])) {
    $cookieParams['domain'] = $cookie->getDomain();
}
*/

Now, you should be able to access the admin panel. You’ll see a warning at the top, complaining about a {{base_url}} setting. This is what prevented you from logging in earlier. Go to System > Configuration from the main menu, and click the “Web” tab in the left sidebar. Expand the “Unsecure” section and change the “Base URL” value to the same preview DNS URL you entered during the installation. You can leave the other “Base…” settings alone. Next, expand the “Secure” section and make the same change to the “Base URL” value. Save your changes.

Magento Base URL configuration menu

Everything should be working now, but remember to uncomment the code in Varien.php. If you have any problems with or comments on your experience with Go Daddy and Magento, please leave them below.

Updates

Here are a couple more problems I came across and how to fix them.

Unable to Insert Uploaded Image into Content

If you get a “target element not found for content update” error when trying to insert an image, it has to do with Magento setting the wrong domain cookie for Go Daddy’s previewdns.com URL. Magento checks the HTTP_HOST server variable when it should be checking for HTTP_X_FORWARDED_HOST first. As a quick fix, open /app/code/core/Mage/Core/Controller/Request/Http.php and change this:

public function getHttpHost($trimPort = true)
{
    if (!isset($_SERVER['HTTP_HOST'])) {
        return false;
    }
    if ($trimPort) {
        $host = explode(':', $_SERVER['HTTP_HOST']);
        return $host[0];
    }
    return $_SERVER['HTTP_HOST'];
}

to this:

public function getHttpHost($trimPort = true)
{
    if (!isset($_SERVER['HTTP_HOST'])) {
        return false;
    }
    if ($trimPort) {
        if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
            $host = explode(':', $_SERVER['HTTP_X_FORWARDED_HOST']);
        } else {
            $host = explode(':', $_SERVER['HTTP_HOST']);
        }
        
        return $host[0];
    }
    return $_SERVER['HTTP_HOST'];
}

Note: any upgrades will probably break this code, but as the preview DNS URL is a temporary measure anyway, it shouldn’t be an issue.

Uploaded Images are Broken on Front-end

If uploaded images aren’t showing up on the website, try deleting the .htaccess file in your /media/wysiwyg folder. Simple as that.