Developer forum

Forum » Dynamicweb 10 » ViewModelTemplateHelper

ViewModelTemplateHelper

Rene Poulsen
Rene Poulsen
Reply

Hi,

We've been using @RenderItemList a lot in DW9 - and also in some cases in DW10. But now it seems to only be working when in a paragraph template.

I've been told to ask for code exmaples here on the forum - and told that we have to look into ViewModelTemplateHelper. Anyone been working with this to replace RenderItemList?


Replies

 
Nicolai Pedersen Dynamicweb Employee
Nicolai Pedersen
Reply

Why do you need it? can you explain what you use it for - my guess is there are new and better ways to do it.

The method looks like below - and if there is now current paragraph it will return an empty string. The actual renderer exposes paragraph information on the paragraph you are rendering - so it has to be there. This change has happened as part of hardening the nullable situation. To avoid exceptions.

You might be able to force a version to work like this:

PageView.Current.CurrentParagraph = new();
@RenderItemList(...)

But I would recommend to do something else.

 public object RenderItemList(object settings)
 {
     ArgumentNullException.ThrowIfNull(settings);

     if (Context.Current is null)
     {
         return string.Empty;
     }

     var pageView = PageView.Current();
     if (pageView is null)
     {
         return string.Empty;
     }

     var paragraph = pageView.CurrentParagraph;
     if (paragraph is null)
     {
         return string.Empty;
     }

     var values = GetNameValueCollection(settings);
     var args = new System.Text.StringBuilder();
     foreach (var key in values.AllKeys)
     {
         if (args.Length > 0)
         {
             args.Append(";");
         }

         args.AppendFormat("{0}:{1}", key, values[key]);
     }

     var cm = new Frontend.ItemPublisher.Frontend()
     {
         Pageview = pageView,
         Paragraph = paragraph
     };

     var moduleOutputResult = cm.GetContentBySettings(args.ToString());
     if(moduleOutputResult is OutputResult and ContentOutputResult contentOutputResult)
         return contentOutputResult.Content;

     return string.Empty;
 }

 
Rene Poulsen
Rene Poulsen
Reply

We need it for the way we create the footer on almost all of our pages. All paragraphs to show in the footer are items of type "FooterColumn" and we used to use RenderItemList to render all of theese columns in the footer.

 
Nicolai Pedersen Dynamicweb Employee
Nicolai Pedersen
Reply

See if my suggested workaround works.

Alternatively rendergrid is an option.

 
Rene Poulsen
Rene Poulsen
Reply

@Nicolai I'm not sure that would work in our case. The place where I want to render the items is not in a paragraph. It's in a partial (layout > footer.cshtml) included in the master template. If I tried to use the above code where you use the CurrentParagraph, wouldn't that fail when I'm not in a paragraph template?

Btw. setting the CurrentParagraph of the PageView is not possible as it's only allowed to get and not set ;-)

 
Rene Poulsen
Rene Poulsen
Reply

Created an Extension like this instead. It's very specific for our footer setup, but just what we need.

using Dynamicweb.Content;
using System.Text;

namespace Application.Extensions
{
    public class FooterExtension
    {
        public static object RenderFooter(int areaId)
        {
            var paragraphService = new ParagraphService();
            var footerParagraphs = paragraphService.GetParagraphsByItemTypes(["footerColumn"]);
            if (footerParagraphs == null) return string.Empty;

            var pageService = new PageService();
            footerParagraphs = footerParagraphs.Where(x => pageService?.GetPage(x.PageID)?.AreaId == areaId);
            if (!footerParagraphs.Any()) return string.Empty;

            var itemService = new ItemService();
            StringBuilder footerContent = new StringBuilder();

            foreach (var footer in footerParagraphs)
            {
                if (footer.ItemId == null) continue;

                var footerItem = itemService.GetItem("footerColumn", footer.ItemId);
                if (footerItem == null) continue;

                var richTextsItemList = Dynamicweb.Content.Items.ItemList.GetItemListById(Convert.ToInt32(footerItem["RichTexts"]));
                if (richTextsItemList == null) continue;

                var footerColClass = richTextsItemList.Relations.Count() > 1 ? "footer__col" : "footer__col footer__col--large";
                footerContent.Append($"<div class=\"{footerColClass}\">");

                foreach (var richTextRelation in richTextsItemList.Relations)
                {
                    var richTextItem = itemService.GetItem("RichText", richTextRelation.Id);
                    if (richTextItem == null) continue;

                    var richText = richTextItem["RichText"];
                    if (richText == null) continue;

                    footerContent.Append($"<div class=\"footer__text rich-text\">{richText}</div>");
                }

                footerContent.Append("</div>");
            }

            return footerContent.ToString();
        }
    }
}
 
Nicolai Pedersen Dynamicweb Employee
Nicolai Pedersen
Reply

Setting the currentparagraph to an empty new paragraph object - not the real paragraph - would cause renderitemlist to work as in DW9. It is a side affect of new null checks in DW10 where render item list will return empty string if current paragraphs is not present. So I think this workaround would work outside a paragraph - e.g. in your footer.

 
Rene Poulsen
Rene Poulsen
Reply

It didn't work. I'm not allowed to set the current paragraph. It only has the get method.

But I'm fine with our Extension as mentioned above. That's just what we need.

 
Nicolai Pedersen Dynamicweb Employee
Nicolai Pedersen
Reply
This post has been marked as an answer

Ah - PageView.Current().SetCurrentParagraph

Not easy!

Votes for this answer: 1
 
Rene Poulsen
Rene Poulsen
Reply

Off course. Didn't notice that. That would probably fix it. I'm goint with our Extension for now though. We have some other RenderItemList setups, but they are inside paragraph templates, so they are working just fine. Is the plan to remove the RenderItemList? Or is it just fine using it in paragraph templates?

 

You must be logged in to post in the forum