Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • SteveMid 25 posts 127 karma points
    Jul 10, 2017 @ 09:25
    SteveMid
    0

    I would like to develop a FAQ section for an Umbraco site I'm working on.

    The questions & answers on the FAQ should be maintained by the client, and view-able on a couple of pages of the site (as side-bars on the 'contact us' page and the 'search results' page).

    I'm still learning Umbraco so would appreciate some advice on the best way to achieve this.

    I'm guessing that I should create a Partial View Macro file to display the FAQs (as it can be re-used on multiple pages) but I'm not sure how to store the data in a way the client can maintain the questions and answers, as they won't be under a single-page in the content section.

    Will this require some custom database work, or is there an easier way to achieve this with the CMS?

  • Paul Seal 524 posts 2889 karma points MVP 6x c-trib
    Jul 10, 2017 @ 16:29
    Paul Seal
    1

    Hi Steve Whenever I do FAQs, I usually use something like archetype or Nested content.

    They allow you to have a list of items, one umbraco document type property. And each item can have more than one property on it.

    So you would have a list of FAQs Each FAQ would have a question property and an answer property

    You can create a surface controller called FAQs and have a Render Action method on it called RenderFAQs which load a model and pass it to a partial view.

    It can then be called from any template.

    Paul

  • Francielle 65 posts 279 karma points
    Jul 10, 2017 @ 17:26
    Francielle
    1

    I did a FAQ page with Nested Content: https://our.umbraco.org/projects/backoffice-extensions/nested-content/ and created a field for Question and Answer. My FAQ was rendered in a single page, so I just did the below on a view, but you could create a partial and render it in the pages you want to:

     @{
        var items = Model.GetPropertyValue<IEnumerable<IPublishedContent>>("faQQuestions");
        var count = 0;
    
        foreach (var item in items)
        {
            count = count + 1;
    
    
        <div class="question">
            <div class="heading" data-toggle="collapse" data-target="@String.Concat("#question",count)" aria-expanded="false">
                <div class="-icon">
                    <h2>@String.Concat("Q", count)</h2>
                </div>
                <div class="title-question">
                    <h3>@item.GetPropertyValue("question")</h3>
                </div>
                <div class="icon-right"></div>
            </div>
            <div class="collapse" id="@String.Concat("question",count)">
                <div class="text-question">
                    <p>@item.GetPropertyValue("answer")</p>
                </div>
            </div>
        </div>
    }
    
  • SteveMid 25 posts 127 karma points
    Jul 12, 2017 @ 13:57
    SteveMid
    0

    Thanks to both. I will give Nested Content a try and see if I can figure it out (and post my findings here)

  • Dirk De Grave 4541 posts 6021 karma points MVP 3x admin c-trib
    Jul 12, 2017 @ 14:40
    Dirk De Grave
    2

    while nested content is an option, it's still too much tied to that specific page you add the nested content property to imho (you'll most probably have to store it on the top level doc/node in the tree for easy retrieval from your ocde.

    if you only need to list those items on other pages (ie, you don't need to display a single faq item as a "page"), i'd go with storing all of your items in a different "folder" somewhere in the tree (could also be root level) and always retrieve the items from there.

    essentially, the output will be the same, but it's less tied to a specific page and separates the concerns.

    my 0.02$

    --Dirk

  • SteveMid 25 posts 127 karma points
    Jul 13, 2017 @ 14:31
    SteveMid
    0

    I have managed to get it working, but have run across a problem - perhaps related to Dirk's concerns.

    I added the Nested Content to the 'Contact Us' page so the users can administer the FAQs from there, and created a partial view that renders the questions in a nice accordion as hoped.

    But... if I try to use this partial view on another page, it produces an error, which I'm fairly sure is due to the fact that the Nested Content is on a different page.

    Is there a way I can update this line of code so it gets the "myFAQs" PropertyValue from a specific Umbraco page using its ID?

     var items = Model.GetPropertyValue<IEnumerable<IPublishedContent>>("myFAQs");
    

    Thanks again,

  • Marcio Goularte 374 posts 1346 karma points
    Jul 13, 2017 @ 14:34
  • Dirk De Grave 4541 posts 6021 karma points MVP 3x admin c-trib
    Jul 13, 2017 @ 14:34
    Dirk De Grave
    0

    Yup, you can specify a 2nd param on the GetPropertyValue() (has a couple of overloads) to find the value "recursively", so if it can"t be find on the current Model (or page), it'll look up it's ancestors until it found some info.

    Assumes you're adding the nested content on the top level, so it can be "found" from anywhere of the child nodes.

    --Dirk

  • SteveMid 25 posts 127 karma points
    Jul 13, 2017 @ 15:40
    SteveMid
    0

    I am struggling a bit with this one (it's all still very new to me).

    I can't find details of the overloads, so tried:

    var items = Model.GetPropertyValue<IEnumerable<IPublishedContent>>("myFAQs", true);
    

    and

    var items = Model.AncestorOrSelf().GetPropertyValue<IEnumerable<IPublishedContent>>("myFAQs");
    

    but still get a "Object reference not set to an instance of an object." when used on any page other than the Contact-Us page (where the Nested Content is)

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Jul 13, 2017 @ 15:45
    Nicholas Westby
    0

    but still get a "Object reference not set to an instance of an object." when used on any page other than the Contact-Us page (where the Nested Content is)

    Why have you placed it on the contact us page? Why not try placing it on the homepage?

  • SteveMid 25 posts 127 karma points
    Jul 13, 2017 @ 15:56
    SteveMid
    0

    I figured that from a users' perspective, it would make sense to reside there, as the FAQ is always shown on the Contact-Us page (but never on the homepage, so they wouldn't naturally think to look there to update it).

  • Francielle 65 posts 279 karma points
    Jul 13, 2017 @ 15:59
    Francielle
    1

    Well, If it takes too long to solve this, you could use the package Marcio posted above or create a child doctype with question and answer below the contact us page and just do a foreach with the ContactUs.children inside a macro partial and render it anywhere you want.

  • SteveMid 25 posts 127 karma points
    Jul 14, 2017 @ 10:13
    SteveMid
    0

    I would quite like to figure-out how to achieve this with Nested Content (as I've got this far, and it's something I'd possibly need to achieve in the future - not just with FAQs).

    I am struggling with how to do the foreach loop inside the partial view though. The code I mention above only works if used on the Contact page - I can't find a way of specifying a different 'source' page (by ID or whatever).

    Any tips would be appreciated - I'm so close!

  • Dirk De Grave 4541 posts 6021 karma points MVP 3x admin c-trib
    Jul 14, 2017 @ 10:20
    Dirk De Grave
    0

    SteveMid,

    If you want to go the nested content route (which is fine), i'd suggest you explain your content structure and some code snippets you've got so far, makes it easier to grasp the context (for us people trying to help you) and provide more specific detailed info on how to accomplish what you want...

    --Dirk

  • SteveMid 25 posts 127 karma points
    Jul 14, 2017 @ 14:08
    SteveMid
    0

    OK, so to clarify... I'm trying to add a FAQ section to a site that is to appear on two or more pages (currently the 'contact us' page and the 'search results' page)

    Both pages are directly under the Homepage

    I used Nested Content to allow a FAQ document type (just question and answer) to be repeated, and added this to the Contact Us page, for useability reasons.

    I wrote a partial view that displays the FAQs, which works fine on the Contact Us page, but not on the Search Results page. I think this is because it can't retrieve the content, as the script only looks for the values in Ancestor or Self, and Contact Us is neither - it's a sibling I guess. I was thinking maybe there was a way to hard-code the Contact Us page ID to the script so it knew where to look for the FAQs

    I have made an Imgur gallery of screenshots to help clarify http://imgur.com/a/jLK2n

    As I mentioned, I'm still quite new to this Umbraco / C# / MVC lark, so please forgive any inaccuracies in my description or my method, and if you need any further information, please let me know.

    Thanks once again for the help.

  • Dirk De Grave 4541 posts 6021 karma points MVP 3x admin c-trib
    Jul 14, 2017 @ 14:17
    Dirk De Grave
    0

    Makes more sense now....

    So, the trick is to find the "Contact us" page from any other page, which is pretty simple as you've probably got only one contact page (I mean, your contact page is if a specific document type and there's only one instance of this document type, right)?

    If so, try this snippet:

    Model.Content.Site().Children.First(x => x.IsDocumentType("aliasOfContactPage");
    

    Can be used from your partial

    Model.Content //= page currently requested
    
    .Site() // finds the top most ancestor ("Home" in your case)
    
    .First(x => x.IsdDocumentType("alias")) // Fetches first child node of your "Home" which is of specific type "alias"
    

    So, you only need to change "alias" to the exact alias of the document type that your "Contact us" page is an instance of.

    Let us know how it goes.

    --Dirk

  • SteveMid 25 posts 127 karma points
    Jul 14, 2017 @ 14:26
    SteveMid
    0

    Thanks for the swift response Dirk,

    I gave that a shot, but am receiving the following error:

    Compiler Error Message: CS1061: 'Umbraco.Core.Models.IPublishedContent' does not contain a definition for 'Content' and no extension method 'Content' accepting a first argument of type 'Umbraco.Core.Models.IPublishedContent' could be found (are you missing a using directive or an assembly reference?)
    

    I currently have two @inherits at the top of the page to get it to work previously, but I think I read that there should only be one? (I tried with just each)

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    
    @inherits Umbraco.Web.Mvc.UmbracoViewPage
    
  • Dirk De Grave 4541 posts 6021 karma points MVP 3x admin c-trib
    Jul 14, 2017 @ 14:34
    Dirk De Grave
    0

    you mentioned a partial view macro in your original post, so just created one on an local dev environment to check... should be

    @inherits Umbraco.Web.Macros.PartialViewMacroPage
    

    And you should be able to use CurrentPage instead of Model.Content as I said in previous reply (haven't done much partial view macro's tbh)

    Can you try that?

    --Dirk

  • SteveMid 25 posts 127 karma points
    Jul 14, 2017 @ 14:42
    SteveMid
    0

    I copied the script into a Partial View Macro file and inserted that into the two page templates.

    The pages render without the big yellow screen of death, but where the macro content should appear, there is the following error message:

    Error loading Partial View script (file: ~/Views/MacroPartials/New ShowFAQ.cshtml)
    

    ..which isn't so useful when it comes to debugging!

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Jul 14, 2017 @ 14:50
    Nicholas Westby
    0

    To better troubleshoot macros, use this setting in ~/Config/umbracoSettings.config:

    <MacroErrors>throw</MacroErrors>
    

    You'll get a normal exception at that point.

  • SteveMid 25 posts 127 karma points
    Jul 14, 2017 @ 14:53
    SteveMid
    0

    Thanks Nicholas (I'm learning lots about Umbraco from this!)

    The problem with the macro appears to be the foreach loop

     CS1579: foreach statement cannot operate on variables of type 'Umbraco.Core.Models.IPublishedContent' because 'Umbraco.Core.Models.IPublishedContent' does not contain a public definition for 'GetEnumerator'
    
  • Dirk De Grave 4541 posts 6021 karma points MVP 3x admin c-trib
    Jul 14, 2017 @ 14:58
    Dirk De Grave
    0

    Can you show the code of your partial view macro file?

    --Dirk

  • SteveMid 25 posts 127 karma points
    Jul 14, 2017 @ 15:03
    SteveMid
    0
    @inherits Umbraco.Web.Macros.PartialViewMacroPage
    
    
    <div class="panel-group" id="accordion">
    
    
    @{
    
                //var umbracoPageId = 1057;
    
                var items = Model.Content.Site().Children.First(x => x.IsDocumentType("ContactPage"));
                var counter = 0;
    
    
    
        foreach(var item in items)
        {
    
    <div class="panel panel-default">
        <div class="panel-heading">
          <h4 class="panel-title">
            <a data-toggle="collapse" data-parent="#accordion" href="#collapse@(counter)">
                @item.GetPropertyValue("question")
            </a>
          </h4>
        </div>
        <div id="collapse@(counter)" class="panel-collapse collapse">
          <div class="panel-body">
            @Umbraco.Field(item, "answer")
        </div>
            </div>
          </div>        
    
        counter++;
        }
    
    
    }
    
    </div>
    
  • Dirk De Grave 4541 posts 6021 karma points MVP 3x admin c-trib
    Jul 14, 2017 @ 15:11
    Dirk De Grave
    0

    Ok, here we go

    Must change Model.Content() with CurrentPage

    As we do .First(), it will only return the first element, while you're trying to iterate afterwards, so this one is the culprit at the moment

    var item = CurrentPage.Site().Children.First(x => x.IsDocumentType("ContactPage")
    

    item will now be the "Contact us" page, so from there, you have to take the nested property value

    var nestedContent = item.GetPropertyValue<IEnumerable<IPublishedContent>>("propertyAlias");
    

    Change "propertyAlias" with the alias of your nested content property defined on your "ContactPage" documentType

    and from there, you should be able to do the loop

    foreach(var content in nestedContent) {...}
    

    --Dirk

  • SteveMid 25 posts 127 karma points
    Jul 14, 2017 @ 15:33
    SteveMid
    0

    I gave that a go. It took me a little bit of head-scratching because there was a missing bracket but I think I interpreted your suggestion correctly and gave it a go, but now we get:

    Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately. 
    
    Compiler Error Message: CS1977: Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type
    
    Source Error:
    
    
    Line 3:  <div class="panel-group" id="accordion">
    Line 4:  @{
    Line 5:              var item = CurrentPage.Site().Children.First(x => x.IsDocumentType("ContactPage"));
    Line 6:              
    Line 7:              var nestedContent = item.GetPropertyValue<IEnumerable<IPublishedContent>>("myFAQs");
    

    (it's line 5 that is highlighted in red on the error page)

  • Dirk De Grave 4541 posts 6021 karma points MVP 3x admin c-trib
    Jul 14, 2017 @ 14:53
    Dirk De Grave
    0

    Hmm, not good, for sake of testing, did the same on my local box.

    Create a partial view macro file (in developer section), check to create a macro, choose "List Child Pages from Current Page") as starting point template.

    Don't need to change the template code, we're just going to verify if it works on your box

    Go to your template (take the template of your "Home" page) and insert the macro you've just created

    Browse the "Home" page and you should get a list (ul/li) of your pages, right?

    If so, we're on the right track, otherwise... well, need to find what's going wrong.

    --Dirk

  • SteveMid 25 posts 127 karma points
    Jul 14, 2017 @ 14:58
    SteveMid
    0

    Hi Dirk,

    I followed the above, and yes... that partial view macro worked fine on the homepage.

    Did you spot my feedback above that (now) shows the error thrown?

Please Sign in or register to post replies

Write your reply to:

Draft