Example #1
0
        public Control RenderMacro(Hashtable pageElements, int documentId)
        {
            TraceInfo("renderMacro", string.Format("Rendering started (macro: {0}, type: {1}, cacheRate: {2})", Name, MacroType, Model.CacheDuration));

            StateHelper.SetContextValue(MacrosAddedKey, StateHelper.GetContextValue <int>(MacrosAddedKey) + 1);

            String  macroHtml    = null;
            Control macroControl = null;

            // zb-00037 #29875 : parse attributes here (and before anything else)
            foreach (var prop in Model.Properties)
            {
                prop.Value = helper.parseAttribute(pageElements, prop.Value);
            }

            Model.CacheIdentifier = GetCacheIdentifier(Model);


            if (Model.CacheDuration > 0)
            {
                if (CacheMacroAsString(Model))
                {
                    macroHtml = _macroCache["macroHtml_" + Model.CacheIdentifier] as String;

                    // FlorisRobbemont:
                    // An empty string means: macroHtml has been cached before, but didn't had any output (Macro doesn't need to be rendered again)
                    // An empty reference (null) means: macroHtml has NOT been cached before
                    if (macroHtml != null)
                    {
                        if (MacroNeedsToBeClearedFromCache(Model, "macroHtml_DateAdded_" + Model.CacheIdentifier))
                        {
                            macroHtml = null;
                            TraceInfo("renderMacro", string.Format("Macro removed from cache due to file change '{0}'.", Model.CacheIdentifier));
                        }
                        else
                        {
                            TraceInfo("renderMacro", string.Format("Macro Content loaded from cache '{0}'.", Model.CacheIdentifier));
                        }
                    }
                }
                else
                {
                    var cacheContent = _macroCache["macroControl_" + Model.CacheIdentifier] as MacroCacheContent;

                    if (cacheContent != null)
                    {
                        macroControl    = cacheContent.Content;
                        macroControl.ID = cacheContent.ID;

                        if (MacroNeedsToBeClearedFromCache(Model, "macroControl_DateAdded_" + Model.CacheIdentifier))
                        {
                            TraceInfo("renderMacro", string.Format("Macro removed from cache due to file change '{0}'.", Model.CacheIdentifier));
                            macroControl = null;
                        }
                        else
                        {
                            TraceInfo("renderMacro", string.Format("Macro Control loaded from cache '{0}'.", Model.CacheIdentifier));
                        }
                    }
                }
            }

            // FlorisRobbemont: Empty macroHtml (not null, but "") doesn't mean a re-render is necessary
            if (macroHtml == null && macroControl == null)
            {
                var renderFailed = false;
                var macroType    = Model.MacroType != MacroTypes.Unknown ? (int)Model.MacroType : MacroType;
                switch (macroType)
                {
                case (int)MacroTypes.XSLT:
                    macroControl = loadMacroXSLT(this, Model, pageElements);
                    break;

                case (int)MacroTypes.Script:
                    try
                    {
                        TraceInfo("umbracoMacro", "MacroEngine script added (" + ScriptFile + ")");

                        var result = LoadMacroScript(Model, documentId);
                        macroControl = new LiteralControl(result.Result);
                        if (result.ResultException != null)
                        {
                            // we'll throw the error if we run in release mode, show details if we're in release mode!
                            renderFailed = true;
                            if (HttpContext.Current != null && !HttpContext.Current.IsDebuggingEnabled)
                            {
                                throw result.ResultException;
                            }
                        }
                        break;
                    }
                    catch (Exception e)
                    {
                        renderFailed = true;
                        Exceptions.Add(e);
                        Log.Instance.LogError("RenderMacro: " + e);

                        var result = new LiteralControl("Error loading MacroEngine script (file: " + ScriptFile + ")");

                        macroControl = result;

                        break;
                    }

                default:
                    if (GlobalSettings.DebugMode)
                    {
                        macroControl = new LiteralControl("&lt;Macro: " + Name + " (" + ScriptAssembly + "," + ScriptType + ")&gt;");
                    }
                    break;
                }

                // Add result to cache if successful
                if (!renderFailed && Model.CacheDuration > 0)
                {
                    // do not add to cache if there's no member and it should cache by personalization
                    if (!Model.CacheByMember || (Model.CacheByMember && Member.GetCurrentMember() != null))
                    {
                        if (macroControl != null)
                        {
                            // NH: Scripts and XSLT can be generated as strings, but not controls as page events wouldn't be hit (such as Page_Load, etc)
                            if (CacheMacroAsString(Model))
                            {
                                string outputCacheString;

                                using (var sw = new StringWriter())
                                {
                                    var hw = new HtmlTextWriter(sw);
                                    macroControl.RenderControl(hw);

                                    outputCacheString = sw.ToString();
                                }

                                _macroCache.Insert("macroHtml_" + Model.CacheIdentifier, outputCacheString, null, DateTime.Now.AddSeconds(Model.CacheDuration), TimeSpan.Zero, CacheItemPriority.NotRemovable,                                 //FlorisRobbemont: issue #27610 -> Macro output cache should not be removable

                                                   null);


                                _macroCache.Insert("macroHtml_DateAdded_" + Model.CacheIdentifier, DateTime.Now, null, DateTime.Now.AddSeconds(Model.CacheDuration), TimeSpan.Zero, CacheItemPriority.NotRemovable,                                 //FlorisRobbemont: issue #27610 -> Macro output cache should not be removable
                                                   null);

                                // zb-00003 #29470 : replace by text if not already text
                                // otherwise it is rendered twice
                                if (!(macroControl is LiteralControl))
                                {
                                    macroControl = new LiteralControl(outputCacheString);
                                }

                                TraceInfo("renderMacro", string.Format("Macro Content saved to cache '{0}'.", Model.CacheIdentifier));
                            }

                            else
                            {
                                _macroCache.Insert("macroControl_" + Model.CacheIdentifier, new MacroCacheContent(macroControl, macroControl.ID), null, DateTime.Now.AddSeconds(Model.CacheDuration), TimeSpan.Zero, CacheItemPriority.NotRemovable,                                 //FlorisRobbemont: issue #27610 -> Macro output cache should not be removable
                                                   null);


                                _macroCache.Insert("macroControl_DateAdded_" + Model.CacheIdentifier, DateTime.Now, null, DateTime.Now.AddSeconds(Model.CacheDuration), TimeSpan.Zero, CacheItemPriority.NotRemovable,                                 //FlorisRobbemont: issue #27610 -> Macro output cache should not be removable
                                                   null);

                                TraceInfo("renderMacro", string.Format("Macro Control saved to cache '{0}'.", Model.CacheIdentifier));
                            }
                        }
                    }
                }
            }
            else if (macroControl == null)
            {
                macroControl = new LiteralControl(macroHtml);
            }

            return(macroControl);
        }