Translated File Action

This type of extension is called whenever the Beebox creates a translated file in the "out" directory of a project. This can be triggered manually from the Beebox UI or by an automatic operation. Some use cases:

  • Copy the translated file to another location
  • Rename translated files, e.g. if you need to suffix or prefix file names.
  • Store translated files to a content management system
  • Track for logging purposes or triggering other actions

 

Adding the extension is done in a few steps:

  1. Add a class that extendst BeeboxTranslatedFileAction.
  2. Code the Process() method. It is called with full details per created translated file.
  3. Compile and install your dll.

The code below is a sample implementation. All interface methods are verbosely commented and should be self-explanatory. 


Renaming files

If you plan to rename translated files, make sure to always leave the original translated file unchanged. Instead, create a copy of the file and save it under a different name (and ideally in a different location to avoid conflicts).

 

Configuration options

The sample implementation below copies and renames translated files according to a user configurable pattern: Each file is copied to out\_copy\... and the file name is prefixed with the target language code.

We added code to permit Beebox administrator to customize the target folder (_copy) and the file renaming individually per project.

We also override the EnableByDefault property and return false. This means that this extension is disabled by default in all projects. The Beebox administrator can then enable it for those projects it shall be used. This is done in the project settings page.

Sample class

The Beebox extension below copies and renames translated files.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Wordbee.Beebox.Extensibility;
using System.IO;
 
 
namespace Acme.PseudoTranslationSample
{
 
	public class SampleTranslatedFileAction : BeeboxTranslatedFileAction
	{
 
		/// <summary>
		/// Gets the globally unique id of this extension.
		/// </summary>
		public override string ExtensionID { get { return "acme-tfa"; } }
 
 
		/// <summary>
		/// Gets if the extension is by default enabled. If false, then it must be enabled explicitly in each
		/// Beebox project from the Beebox Admin UI.
		/// </summary>
		public override bool EnableByDefault { get { return false; } }
 
 
 
		/// <summary>
		/// Gets a name. Displayed in the Beebox extension manager page.
		/// </summary>
		public override string Name { get { return "Copy translated files"; } }
 
 
		/// <summary>
		/// Gets a description. Displayed in the Beebox extension manager page.
		/// </summary>
		public override string Description { get { return "Copies all translated files to another location."; } }
 
 
		/// <summary>
		/// Gets version number. Displayed in the Beebox extension manager page.
		/// </summary>
		public override string Version { get { return "1.0"; } }
 
 
		/// <summary>
		/// Gets the author. Displayed in the Beebox extension manager page.
		/// </summary>
		public override string Author { get { return "Acme Ltd"; } }
 
 
 
		/// <summary>
		/// Gets optional help description (not html!) of the configuration parameter.
		/// By returning a non-null value, you explicitly tell the Beebox that this extension has a configurable parameter.
		/// </summary>
		public override string ParameterHelp 
		{ 
			get
			{
				return 
					"Specify the sub directory inside out folder to which files will be copied." +
					"Then the name transformation pattern. Separate with semi-colon.\n " +
					"The name pattern may contain:\n " +
					"{name} : The file name without extension.\n " +
					"{extension} : The file extension.\n " +
					"{tlocale} : The target language code.\n " +
					"{slocale} : The source language code.\n ";
			} 
		}
 
 
 
		/// <summary>
		/// Gets the default value of the parameter. Default can be changed by user.
		/// </summary>
		public override string ParameterDefault { get { return @"_copy; {tlocale}-{name}{extension}"; } }
 
 
 
		/// <summary>
		/// Validates the user parameters.
		/// Return null if ok, otherwise return an error text.
		/// </summary>
		/// <param name="parameter">The parameter edited by a user.</param>
		/// <returns>Null: parameter is ok. Otherwise return an error message.</returns>
		public override string ValidateParameter(string parameter)
		{
			try
			{
				if (string.IsNullOrWhiteSpace(parameter)) return null;
				var arr = parameter.Split(';');
				if (arr.Length != 2) return "Specify a subdirectory followed by semi-colon followed by name pattern.";
 
				// Here you need to check each array element in detail.
				if (string.IsNullOrWhiteSpace(arr[0])) return "The subdirectory name is missing.";
				if (string.IsNullOrWhiteSpace(arr[1])) return "The name transformation pattern is missing.";
 
				return null;
			}
			catch (Exception e)
			{
				return "The parameter is not correct.";
			}
		}
 
 
 
		/// <summary>
		/// Called whenever a translated file was created in the OUT directory. Its location is:
		/// {outdirectory}\{locale}\{relativepath}
		/// When your code shall copy the file to another location, please keep in mind that the relativepath can include directories.
		/// Example: "chapter\myfile1.doc", "data.xml", etc.
		/// </summary>
		/// <param name="projectkey">The project key</param>
		/// <param name="path">The full path of the created translated file.</param>
		/// <param name="outdirectory">The "OUT" directory path.</param>
		/// <param name="targetlocale">The target language code</param>
		/// <param name="filename">The relative path of the file with respect to {out directory}\{locale}(\){projectfolder}</param>
		/// <param name="sourcelocale">The source language code</param>
		/// <param name="configuration">The extension's parameters. You need to implement the respective virtual methods to permit configuring the parameter individually per project.</param>
		public override void Process(
				string projectkey, 
				string path, 
				string outdirectory, 
				string targetlocale, 
				string filename, 
				string sourcelocale, 
				IExtensionConfiguration configuration)
		{
			string subdirectory, namepattern;
 
			// Get parameters
			var parameter = configuration.Parameter ?? ParameterDefault;
			var arr = parameter.Split(';');
			subdirectory = arr[0].Trim();
			namepattern = arr[1].Trim();
 
			// Calculate target path
			string name = Path.GetFileName(filename);
			string newname = namepattern
								.Replace("{name}", Path.GetFileNameWithoutExtension(name))
								.Replace("{extension}", Path.GetExtension(name))
								.Replace("{tlocale}", targetlocale)
								.Replace("{slocale}", sourcelocale);
 
			string targetPath = Path.Combine(outdirectory, subdirectory, targetlocale, Path.GetDirectoryName(filename), newname);
 
			// Ensure that the file's directory exists. If not, create it now. Will raise exception if the target path is invalid.
			EnsureDirectoryExists(targetPath);
 
			// Copy file. May raise exception if the target file cannot be written.
			File.Copy(path, targetPath, true);
 
		}
 
 
 
		/// <summary>
		/// Creates all parent directories for the file path if these do not exist.
		/// </summary>
		/// <param name="filepath"></param>
		private static void EnsureDirectoryExists(string filepath)
		{
			string d = Path.GetDirectoryName(filepath);
			if (string.IsNullOrEmpty(d)) throw new Exception(string.Format("The file path '{0}' seems to be invalid. Failed to create all directories.", filepath));
			if (!Directory.Exists(d))
			{
				EnsureDirectoryExists(d);
				Directory.CreateDirectory(d);
			}
		}
 
 
	}
}
 
 

	

 

 

Copyright Wordbee - Buzzin' Outside the Box since 2008