Just in Chronicles

Life as a Voyage

Posts Tagged ‘Umbraco

Enhanced Preview for Umbraco

leave a comment »

Existing preview function in Umbraco only supports actual pages, not contents shared within a website. This approach is logically correct as shared contents are not independent pages. However, there must be demands to preview shared contents before publishing them.

This Umbraco extension enables for content editors to preview what they have written and how the contents would be looking like, before they publish the contents.

Basic idea is simple. Umbraco provides an alternative template function by using AltTemplate querystring.

This extension allows users to assign certain document types to templates. So, when users click the preview button, this extension starts looking up the configuration values to for document type  Рtemplate mappings.

<enhancedPreviewConfiguration>
    <items>
        <clear />
        <add alias="Product" template="StandardPage" redirectUrl="/products/product/{0}" />
        <add alias="Company" template="StandardPage" redirectUrl="/companies/company/{0}" />
    </items>
</enhancedPreviewConfiguration>

Like the example above, the extension registers a config file, EnhancedPreviewConfiguration.config under /config/ directory. Based on this example, a document type Product will use the template StandardPage for its preview mode. After the preview, the preview page will be redirected to /products/product/[productId] page.

If you guys are interested in, please visit the following websites.

Written by Justin Yoo

31/07/2012 at 17:20

Posted in For .NET

Tagged with , ,

Triming Property Type Value – Description or Validation – While Saving Document Type in Umbraco

leave a comment »

When developers create a document type in Umbraco, they might notice that an extra line – either Line Feed (\n) or Carriage Return (\r), or both – is added into those two fields – Validation and Description – of each property. This extra white space will result in validation errors and prevent the content from saving, in the Content section.

In order to avoid this, the value must be trimmed while retrieving and saving by modifying the source code, UmbracoProject\umbraco\cms\businesslogic\propertytype\propertytype.cs. Find the following code lines from the file and put .Trim() as highlighted.

public string ValidationRegExp
{
	get { return _validationRegExp.Trim(); }
	set
	{
		_validationRegExp = value.Trim();
		InvalidateCache();
		SqlHelper.ExecuteNonQuery(
			"Update cmsPropertyType set validationRegExp = @validationRegExp where id = @id",
			SqlHelper.CreateParameter("@validationRegExp", value.Trim()), SqlHelper.CreateParameter("@id", Id));
	}
}
public string Description
{
	get
	{
		if (_description != null)
		{
			if (!_description.StartsWith("#"))
				return _description.Trim();
			else
			{
				Language lang = Language.GetByCultureCode(Thread.CurrentThread.CurrentCulture.Name);
				if (lang != null)
				{
					if (Dictionary.DictionaryItem.hasKey(_description.Substring(1, _description.Length - 1)))
					{
						var di =
							new Dictionary.DictionaryItem(_description.Substring(1, _description.Length - 1));
						return di.Value(lang.id).Trim();
					}
				}
			}

			return "[" + _description.Trim() + "]";
		}

		return _description.Trim();
	}
	set
	{
		_description = value.Trim();
		InvalidateCache();
		SqlHelper.ExecuteNonQuery(
			"Update cmsPropertyType set description = @description where id = @id",
			SqlHelper.CreateParameter("@description", value.Trim()),
			SqlHelper.CreateParameter("@id", Id));
	}
}
public string GetRawDescription()
{
	return _description.Trim();
}

By adding the .Trim() method, even though it can’t prevent displaying an extra line, but it won’t save the extra line into the database.

Written by Justin Yoo

27/03/2012 at 18:12

uComponents: Multi-Node Tree Picker Data Saving Format Error in Umbraco

leave a comment »

uComponents is a killer extension for Umbraco as it compliments a lot of features that Umbraco lacks or doesn’t have. Nowadays uComponents is a sort of de-facto standard extension because many other extensions are assuming that uComponents is installed.

Once uComponents is installed, several data types used in Umbraco are also installed. Multi-Node Tree Picker (MNTP) which is one of the installed data types is, I believe, the most useful and versatile data type. However, it stores its value as NTEXT type when its value type is set to CSV, which is not quite right.

When you modify contents at the Umbraco back-office, the following error message can be seen.

Your data has been saved, but before you can publish this page there are some errors you need to fix first:

  • [PROPERTY] at [TAB] is not in a correct format

This results from the fact that the value type is set to NTEXT, instead of NVARCHAR. So, once a data type using MNTP is created, the value type should be updated to NVARCHAR directly in SQL.

SELECT
	node.id,
	node.[text],
	dt.*
FROM
	cmsDataType AS dt
	JOIN umbracoNode AS node
		ON dt.nodeId = node.id
WHERE
	dt.controlId = 'c2d6894b-e788-4425-bcf2-308568e3d38b'

Note that the controlId has the value “c2d6894b-e788-4425-bcf2-308568e3d38b” that represents MNTP. Once the query is run, all MNTP data types are listed. They all have NText at their dbType. So they need to be updated to NVarchar by running the following SQL script.

UPDATE
	cmsDataType
   SET
	dbType = 'Nvarchar'
 WHERE
	controlId = 'c2d6894b-e788-4425-bcf2-308568e3d38b'

Now, the MNTP control will have NVarchar data value and will not display the error message above.

Written by Justin Yoo

26/03/2012 at 13:56

How to Add External Error Log to Umbraco with Razor Macro Scripts

leave a comment »

Umbraco Razor macro script is very powerful and handy solution for developers to implement websites quite easily, while XSLT scripts are very hard to read and understand. However, using Razor macro scripts in Umbraco calls error log functions internally, which saves the logs to the database, rather than specific files.

That sometimes gets developers bothered as they have to append “umbDebutShotTrace=true” query string to its URL to debug an error when it occurs. Besides using the “umbDebugShowTrace=true” option, developers want to save that error details to a specific location other than the database. In order to achieve this, Umbraco core needs to be modified and recompiled. The key method is “umbraco.MacroEngines.RazorMacroEngine.Execute()” which is coded in “/umbraco.MacroEngines.Juno/RazorCore/RazorMacroEngine.cs“. Let’s see the code.

public string Execute(MacroModel macro, INode currentPage)
{
	try
	{
		Success = true;
		return ExecuteRazor(macro, currentPage);
	}
	catch (Exception exception)
	{
		Success = false;
		ResultException = exception;
		HttpContext.Current.Trace.Warn("umbracoMacro", string.Format("Error Loading Razor Script (file: {0}) {1} {2}", macro.Name, exception.Message, exception.StackTrace));
		var loading = string.Format("<div style=\"border: 1px solid #990000\">Error loading Razor Script {0}</br/>", macro.ScriptName);
		if (GlobalSettings.DebugMode)
			loading = loading + exception.Message;
		loading = loading + "</div>";

		// Adds the exception to the current HttpContext.Items.
		// Option #1: Using Dictionary<T>
		List<Dictionary<string, string>> logs = (List<Dictionary<string, string>>)HttpContext.Current.Items["umbracoErrorLogItems"];
		if (logs == null)
			logs = new List<Dictionary<string, string>>();
		logs.Add(new Dictionary<string, string>() { { "message", exception.Message }, { "source", exception.Source }, { "stackTrace", exception.StackTrace } });

		// Option #2: Using general Object
		List<object> logs = (List<object>)HttpContext.Current.Items["umbracoErrorLogItems"];
		if (logs == null)
			logs = new List<object>();
		logs.Add(new { Message = exception.Message, Source = exception.Source, StackTrace = exception.StackTrace });

		HttpContext.Current.Items["umbracoErrorLogItems"] = logs;
		return loading;
	}
}

The lines highlighted between 18 and 29 are newly added for the external log saving mechanism. When an exception occurs, HttpContext.Current.Items[“umbracoErrorLogItems”] stores the error details. Option #1 uses Dictionary<T> while Option #2 uses general object.

Then, open the /default.aspx page of the website’s root directory and put the following code bits.

<script runat="server">
	protected void Page_Load(object sender, EventArgs e)
	{
		var logs = Context.Items["umbracoErrorLogItems"];
		if (logs != null)
		{
			foreach (var log in logs)
			YourLogHelper.SaveLog(log);
			Context.Items["umbracoErrorLogItems"] = null;
		}
	}
</script>

Once the page is loaded, if there is any error log details found from HttpContext.Current.Items[“umbracoErrorLogItems”], the highlighted log saving method will be executed. Once all the error log details are saved, the Context.Items[“umbracoErrorLogItems”] has to be cleared for further use.

That’s what I’ve found so far. I know modifying the core source code is not the ideal solution, but it this case might be excused.

Written by Justin Yoo

06/03/2012 at 18:01

Posted in For .NET

Tagged with , ,