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?
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.
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:
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.
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");
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.
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)
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?
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).
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.
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).
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...
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
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.
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)?
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.
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)
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'
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)
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.
FAQ section
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?
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
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:
Thanks to both. I will give Nested Content a try and see if I can figure it out (and post my findings here)
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
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?
Thanks again,
Also has this package:
https://our.umbraco.org/projects/website-utilities/faq-listing/
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
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:
and
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?
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).
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.
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!
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
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.
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:
Can be used from your partial
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
Thanks for the swift response Dirk,
I gave that a shot, but am receiving the following error:
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)
you mentioned a partial view macro in your original post, so just created one on an local dev environment to check... should be
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
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:
..which isn't so useful when it comes to debugging!
To better troubleshoot macros, use this setting in
~/Config/umbracoSettings.config
:You'll get a normal exception at that point.
Thanks Nicholas (I'm learning lots about Umbraco from this!)
The problem with the macro appears to be the foreach loop
Can you show the code of your partial view macro file?
--Dirk
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
item will now be the "Contact us" page, so from there, you have to take the nested property value
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
--Dirk
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:
(it's line 5 that is highlighted in red on the error page)
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
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?
is working on a reply...