예제 #1
0
        /// <summary>
        /// Renders the macro with the specified alias, passing in the specified parameters.
        /// </summary>
        /// <param name="alias">The alias.</param>
        /// <param name="parameters">The parameters.</param>
        /// <returns></returns>
        public IHtmlString RenderMacro(string alias, IDictionary <string, object> parameters)
        {
            if (alias == null)
            {
                throw new ArgumentNullException("alias");
            }
            var containerPage = new FormlessPage();
            var m             = macro.GetMacro(alias);

            if (_umbracoContext.PageId == null)
            {
                throw new InvalidOperationException("Cannot render a macro when UmbracoContext.PageId is null.");
            }
            if (_umbracoContext.PublishedContentRequest == null)
            {
                throw new InvalidOperationException("Cannot render a macro when there is no current PublishedContentRequest.");
            }
            var macroProps = new Hashtable();

            foreach (var i in parameters)
            {
                //TODO: We are doing at ToLower here because for some insane reason the UpdateMacroModel method of macro.cs
                // looks for a lower case match. WTF. the whole macro concept needs to be rewritten.
                macroProps.Add(i.Key.ToLower(), i.Value);
            }
            var macroControl = m.renderMacro(macroProps,
                                             UmbracoContext.Current.PublishedContentRequest.UmbracoPage.Elements,
                                             _umbracoContext.PageId.Value);

            containerPage.Controls.Add(macroControl);
            using (var output = new StringWriter())
            {
                _umbracoContext.HttpContext.Server.Execute(containerPage, output, false);

                //Now, we need to ensure that local links are parsed
                return(new HtmlString(
                           TemplateUtilities.ParseInternalLinks(
                               output.ToString())));
            }
        }
        /// <summary>
        /// Renders an field to the template
        /// </summary>
        /// <param name="currentPage"></param>
        /// <param name="fieldAlias"></param>
        /// <param name="altFieldAlias"></param>
        /// <param name="altText"></param>
        /// <param name="insertBefore"></param>
        /// <param name="insertAfter"></param>
        /// <param name="recursive"></param>
        /// <param name="convertLineBreaks"></param>
        /// <param name="removeParagraphTags"></param>
        /// <param name="casing"></param>
        /// <param name="encoding"></param>
        /// <param name="formatAsDate"></param>
        /// <param name="formatAsDateWithTime"></param>
        /// <param name="formatAsDateWithTimeSeparator"></param>
        //// <param name="formatString"></param>
        /// <returns></returns>
        public IHtmlString Field(IPublishedContent currentPage, string fieldAlias,
                                 string altFieldAlias                 = "", string altText            = "", string insertBefore = "", string insertAfter = "",
                                 bool recursive                       = false, bool convertLineBreaks = false, bool removeParagraphTags = false,
                                 RenderFieldCaseType casing           = RenderFieldCaseType.Unchanged,
                                 RenderFieldEncodingType encoding     = RenderFieldEncodingType.Unchanged,
                                 bool formatAsDate                    = false,
                                 bool formatAsDateWithTime            = false,
                                 string formatAsDateWithTimeSeparator = "")

        //TODO: commented out until as it is not implemented by umbraco:item yet
        //,string formatString = "")
        {
            Mandate.ParameterNotNull(currentPage, "currentPage");
            Mandate.ParameterNotNullOrEmpty(fieldAlias, "fieldAlias");

            //TODO: This is real nasty and we should re-write the 'item' and 'ItemRenderer' class but si fine for now

            var attributes = new Dictionary <string, string>
            {
                { "field", fieldAlias },
                { "recursive", recursive.ToString().ToLowerInvariant() },
                { "useifempty", altFieldAlias },
                { "textifempty", altText },
                { "stripparagraph", removeParagraphTags.ToString().ToLowerInvariant() },
                {
                    "case", casing == RenderFieldCaseType.Lower ? "lower"
                                                                : casing == RenderFieldCaseType.Upper ? "upper"
                                                                        : casing == RenderFieldCaseType.Title ? "title"
                                                                                : string.Empty
                },
                { "inserttextbefore", insertBefore },
                { "inserttextafter", insertAfter },
                { "convertlinebreaks", convertLineBreaks.ToString().ToLowerInvariant() },
                { "formatasdate", formatAsDate.ToString().ToLowerInvariant() },
                { "formatasdatewithtime", formatAsDateWithTime.ToString().ToLowerInvariant() },
                { "formatasdatewithtimeseparator", formatAsDateWithTimeSeparator }
            };

            switch (encoding)
            {
            case RenderFieldEncodingType.Url:
                attributes.Add("urlencode", "true");
                break;

            case RenderFieldEncodingType.Html:
                attributes.Add("htmlencode", "true");
                break;

            case RenderFieldEncodingType.Unchanged:
            default:
                break;
            }

            //need to convert our dictionary over to this weird dictionary type
            var attributesForItem = new AttributeCollectionAdapter(
                new AttributeCollection(
                    new StateBag()));

            foreach (var i in attributes)
            {
                attributesForItem.Add(i.Key, i.Value);
            }



            var item = new Item(currentPage)
            {
                Field            = fieldAlias,
                TextIfEmpty      = altText,
                LegacyAttributes = attributesForItem
            };

            //here we are going to check if we are in the context of an Umbraco routed page, if we are we
            //will leave the NodeId empty since the underlying ItemRenderer will work ever so slightly faster
            //since it already knows about the current page. Otherwise, we'll assign the id based on our
            //currently assigned node. The PublishedContentRequest will be null if:
            // * we are rendering a partial view or child action
            // * we are rendering a view from a custom route
            if ((_umbracoContext.PublishedContentRequest == null ||
                 _umbracoContext.PublishedContentRequest.PublishedContent.Id != currentPage.Id) &&
                currentPage.Id > 0)    // in case we're rendering a detached content (id == 0)
            {
                item.NodeId = currentPage.Id.ToString(CultureInfo.InvariantCulture);
            }


            var containerPage = new FormlessPage();

            containerPage.Controls.Add(item);

            using (var output = new StringWriter())
                using (var htmlWriter = new HtmlTextWriter(output))
                {
                    ItemRenderer.Instance.Init(item);
                    ItemRenderer.Instance.Load(item);
                    ItemRenderer.Instance.Render(item, htmlWriter);

                    //because we are rendering the output through the legacy Item (webforms) stuff, the {localLinks} will already be replaced.
                    return(new HtmlString(output.ToString()));
                }
        }
        /// <summary>
        /// Renders the macro with the specified alias, passing in the specified parameters.
        /// </summary>
        /// <param name="m">The macro.</param>
        /// <param name="parameters">The parameters.</param>
        /// <param name="umbracoPage">The legacy umbraco page object that is required for some macros</param>
        /// <returns></returns>
        internal IHtmlString RenderMacro(macro m, IDictionary <string, object> parameters, page umbracoPage)
        {
            if (umbracoPage == null)
            {
                throw new ArgumentNullException("umbracoPage");
            }
            if (m == null)
            {
                throw new ArgumentNullException("m");
            }

            if (_umbracoContext.PageId == null)
            {
                throw new InvalidOperationException("Cannot render a macro when UmbracoContext.PageId is null.");
            }

            var macroProps = new Hashtable();

            foreach (var i in parameters)
            {
                //TODO: We are doing at ToLower here because for some insane reason the UpdateMacroModel method of macro.cs
                // looks for a lower case match. WTF. the whole macro concept needs to be rewritten.


                //NOTE: the value could have html encoded values, so we need to deal with that
                macroProps.Add(i.Key.ToLowerInvariant(), (i.Value is string) ? HttpUtility.HtmlDecode(i.Value.ToString()) : i.Value);
            }
            var macroControl = m.renderMacro(macroProps,
                                             umbracoPage.Elements,
                                             _umbracoContext.PageId.Value);

            string html;

            if (macroControl is LiteralControl)
            {
                // no need to execute, we already have text
                html = (macroControl as LiteralControl).Text;
            }
            else
            {
                var containerPage = new FormlessPage();
                containerPage.Controls.Add(macroControl);

                using (var output = new StringWriter())
                {
                    // .Execute() does a PushTraceContext/PopTraceContext and writes trace output straight into 'output'
                    // and I do not see how we could wire the trace context to the current context... so it creates dirty
                    // trace output right in the middle of the page.
                    //
                    // The only thing we can do is fully disable trace output while .Execute() runs and restore afterwards
                    // which means trace output is lost if the macro is a control (.ascx or user control) that is invoked
                    // from within Razor -- which makes sense anyway because the control can _not_ run correctly from
                    // within Razor since it will never be inserted into the page pipeline (which may even not exist at all
                    // if we're running MVC).
                    //
                    // I'm sure there's more things that will get lost with this context changing but I guess we'll figure
                    // those out as we go along. One thing we lose is the content type response output.
                    // http://issues.umbraco.org/issue/U4-1599 if it is setup during the macro execution. So
                    // here we'll save the content type response and reset it after execute is called.

                    var contentType    = _umbracoContext.HttpContext.Response.ContentType;
                    var traceIsEnabled = containerPage.Trace.IsEnabled;
                    containerPage.Trace.IsEnabled = false;
                    _umbracoContext.HttpContext.Server.Execute(containerPage, output, true);
                    containerPage.Trace.IsEnabled = traceIsEnabled;
                    //reset the content type
                    _umbracoContext.HttpContext.Response.ContentType = contentType;

                    //Now, we need to ensure that local links are parsed
                    html = TemplateUtilities.ParseInternalLinks(output.ToString());
                }
            }

            return(new HtmlString(html));
        }
예제 #4
0
        /// <summary>
        /// Renders the macro with the specified alias, passing in the specified parameters.
        /// </summary>
        /// <param name="alias">The alias.</param>
        /// <param name="parameters">The parameters.</param>
        /// <returns></returns>
        public IHtmlString RenderMacro(string alias, IDictionary <string, object> parameters)
        {
            if (alias == null)
            {
                throw new ArgumentNullException("alias");
            }

            var m = macro.GetMacro(alias);

            if (_umbracoContext.PageId == null)
            {
                throw new InvalidOperationException("Cannot render a macro when UmbracoContext.PageId is null.");
            }
            if (_umbracoContext.PublishedContentRequest == null)
            {
                throw new InvalidOperationException("Cannot render a macro when there is no current PublishedContentRequest.");
            }
            var macroProps = new Hashtable();

            foreach (var i in parameters)
            {
                //TODO: We are doing at ToLower here because for some insane reason the UpdateMacroModel method of macro.cs
                // looks for a lower case match. WTF. the whole macro concept needs to be rewritten.
                macroProps.Add(i.Key.ToLower(), i.Value);
            }
            var macroControl = m.renderMacro(macroProps,
                                             UmbracoContext.Current.PublishedContentRequest.UmbracoPage.Elements,
                                             _umbracoContext.PageId.Value);

            string html;

            if (macroControl is LiteralControl)
            {
                // no need to execute, we already have text
                html = (macroControl as LiteralControl).Text;
            }
            else
            {
                var containerPage = new FormlessPage();
                containerPage.Controls.Add(macroControl);

                using (var output = new StringWriter())
                {
                    // .Execute() does a PushTraceContext/PopTraceContext and writes trace output straight into 'output'
                    // and I do not see how we could wire the trace context to the current context... so it creates dirty
                    // trace output right in the middle of the page.
                    //
                    // The only thing we can do is fully disable trace output while .Execute() runs and restore afterwards
                    // which means trace output is lost if the macro is a control (.ascx or user control) that is invoked
                    // from within Razor -- which makes sense anyway because the control can _not_ run correctly from
                    // within Razor since it will never be inserted into the page pipeline (which may even not exist at all
                    // if we're running MVC).
                    //
                    var traceIsEnabled = containerPage.Trace.IsEnabled;
                    containerPage.Trace.IsEnabled = false;
                    _umbracoContext.HttpContext.Server.Execute(containerPage, output, false);
                    containerPage.Trace.IsEnabled = traceIsEnabled;

                    //Now, we need to ensure that local links are parsed
                    html = TemplateUtilities.ParseInternalLinks(output.ToString());
                }
            }

            return(new HtmlString(html));
        }
예제 #5
0
        /// <summary>
        /// Renders an field to the template
        /// </summary>
        /// <param name="currentPage"></param>
        /// <param name="fieldAlias"></param>
        /// <param name="altFieldAlias"></param>
        /// <param name="altText"></param>
        /// <param name="insertBefore"></param>
        /// <param name="insertAfter"></param>
        /// <param name="recursive"></param>
        /// <param name="convertLineBreaks"></param>
        /// <param name="removeParagraphTags"></param>
        /// <param name="casing"></param>
        /// <param name="encoding"></param>
        /// <param name="formatAsDate"></param>
        /// <param name="formatAsDateWithTime"></param>
        /// <param name="formatAsDateWithTimeSeparator"></param>
        //// <param name="formatString"></param>
        /// <returns></returns>
        public IHtmlString Field(IPublishedContent currentPage, string fieldAlias,
                                 string altFieldAlias                 = "", string altText            = "", string insertBefore = "", string insertAfter = "",
                                 bool recursive                       = false, bool convertLineBreaks = false, bool removeParagraphTags = false,
                                 RenderFieldCaseType casing           = RenderFieldCaseType.Unchanged,
                                 RenderFieldEncodingType encoding     = RenderFieldEncodingType.Unchanged,
                                 bool formatAsDate                    = false,
                                 bool formatAsDateWithTime            = false,
                                 string formatAsDateWithTimeSeparator = "")

        //TODO: commented out until as it is not implemented by umbraco:item yet
        //,string formatString = "")
        {
            Mandate.ParameterNotNull(currentPage, "currentPage");
            Mandate.ParameterNotNullOrEmpty(fieldAlias, "fieldAlias");

            //TODO: This is real nasty and we should re-write the 'item' and 'ItemRenderer' class but si fine for now

            var attributes = new Dictionary <string, string>
            {
                { "field", fieldAlias },
                { "recursive", recursive.ToString().ToLowerInvariant() },
                { "useifempty", altFieldAlias },
                { "textifempty", altText },
                { "stripparagraph", removeParagraphTags.ToString().ToLowerInvariant() },
                {
                    "case", casing == RenderFieldCaseType.Lower ? "lower"
                                                                : casing == RenderFieldCaseType.Upper ? "upper"
                                                                        : casing == RenderFieldCaseType.Title ? "title"
                                                                                : string.Empty
                },
                { "inserttextbefore", insertBefore },
                { "inserttextafter", insertAfter },
                { "convertlinebreaks", convertLineBreaks.ToString().ToLowerInvariant() },
                { "formatasdate", formatAsDate.ToString().ToLowerInvariant() },
                { "formatasdatewithtime", formatAsDateWithTime.ToString().ToLowerInvariant() },
                { "formatasdatewithtimeseparator", formatAsDateWithTimeSeparator }
            };

            switch (encoding)
            {
            case RenderFieldEncodingType.Url:
                attributes.Add("urlencode", "true");
                break;

            case RenderFieldEncodingType.Html:
                attributes.Add("htmlencode", "true");
                break;

            case RenderFieldEncodingType.Unchanged:
            default:
                break;
            }

            //need to convert our dictionary over to this weird dictionary type
            var attributesForItem = new AttributeCollectionAdapter(
                new AttributeCollection(
                    new StateBag()));

            foreach (var i in attributes)
            {
                attributesForItem.Add(i.Key, i.Value);
            }



            var item = new Item()
            {
                //NodeId = currentPage.Id.ToString();
                Field            = fieldAlias,
                TextIfEmpty      = altText,
                LegacyAttributes = attributesForItem
            };

            //this is here to figure out if this request is in the context of a partial
            if (_umbracoContext.PublishedContentRequest.PublishedContent.Id != _currentPage.Id)
            {
                item.NodeId = _currentPage.Id.ToString();
            }


            var containerPage = new FormlessPage();

            containerPage.Controls.Add(item);

            using (var output = new StringWriter())
                using (var htmlWriter = new HtmlTextWriter(output))
                {
                    ItemRenderer.Instance.Init(item);
                    ItemRenderer.Instance.Load(item);
                    ItemRenderer.Instance.Render(item, htmlWriter);

                    //because we are rendering the output through the legacy Item (webforms) stuff, the {localLinks} will already be replaced.
                    return(new HtmlString(output.ToString()));
                }
        }