Using a Parameter from a DocType To Set Paramater for Macro in Template
I have a template with a lightbox macro inserted within the template #1. It has one parameter that I would like to set from the docType of a piece of content that the template #1 is using. Is this even possible?
Template #1 has a bxslider in which the docType of SlideshowItem exists. I am trying to be able to select on each SlideshowItem the media folder for a lightbox that corisponds to that slide within the bxslider.
There is a special syntax for passing the value of a doctype property directly into a macro parameter.
So if your macro is called 'DisplayLightbox', and your Macro Parameter is setup with alias called 'mediaFolderId' and your doctype has a media picker property called 'SelectMediaFolder' then in your template you can pass this into your macro like so:
@Umbraco.RenderMacro("DisplayLightbox", new {mediaFolderId = "[#SelectMediaFolder]"})
ie [#propertyAliasName] means take the macro parameter from the current doc type property with that alias.
You also have available:
[$propertyAliasName] that will look recursively up your content tree for a property with the alias to supply the macro with a value - useful for 'global properties'.
[@querystringName] to take the parameter from a querystring value
[%sessionKeyName] to take the parameter value from the session object.
you can also 'chain these' to look for say a querystring value first, and if it doesn't exist take the doc type value eg:
@Umbraco.RenderMacro("DisplayLightbox", new {mediaFolderId = "[@id],[#SelectMediaFolder],5"})
Which would look first for a querystring parameter called id, if not present look for the doctype property 'SelectMediaFolder' and if that wasn't present use the value 5!
Marc,
First of all I am using Umbraco v 6.1.6, and couldn't place the line of code you posted without an assembly error. But...
What if I need to pass the docType parameter to a macro that isn't placed on the template, but rather inserted on a content item that is a docType "slideshowItem"?
The slideshowItem doesn't have a template, as it is just a holder (docType) for an image, caption and, I am hoping, the insert lightbox macro (within a rich text editor field).
This way I could potentially have multiple slides in a bxslider that each could launch their own lightbox when clicked.
within this you wish to insert a 'display Slide Show' Macro
At the point of insertion, the macro will have a parameter (type ContentPicker) to allow the editor to pick a node (single node) from somewhere in the content tree, of document type 'SlideShow', underneath this node, will be further nodes based on a 'SlideShowItem' doctype, ie one node for each slide.
So in your macro Partial view that implements your macro (are you using Partial Views or DynamicNode Razor ?) you should be able to read the picked content node id from the parameter using:
var pickedSlideShowId = Model.GetParameterValue<int>("parameterAlias")
although this helper extension may not actually be available in Umbraco 6.1.6 ...
otherwise I think it was
Model.MacroParameters["parameterAlias"]
in earlier versions.
With the Id of the picked 'slide show' content you could then use
var pickedSlideShow = Umbraco.TypedContent(pickedSlideShowId);
to get a reference to the slide show node and it's properties, furthermore use
var slides = pickedSlideShow.Children().Where(f=>f.IsVisible());
to get a list of the slides to loop through and write out the slideshow html.
Or do you mean the macro parameter contentPicker will just pick a single SlideShowItem node, in which case just read the picked Id, and the above to get a reference to that node's properties / slide image etc - for the lightbox.
Or do you mean the macro is just for positioning and the relevant slides are picked on the underlying standardPage doctype - if so in the macro partial view, you can read the properties of the underlying document type content via Model.Content.GetPropertyValue etc
The slideshow on this page is a bxslider razor macro embedded within the homepage template. The macro pulls images and other parameters from a docType "SlideshowItem" into each slide for the bxslider macro.
Because each slide (SlideshowItem), does not have a template and that I would like to be able to have different colorbox (lightbox)'s for multiple SlideshowItems I had to make the colorbox macro place-able into a rich text area on the editor, but since the colorbox macro uses the same parameter of "SlideFolder" within it's macro, it will always use the last selected SlideFolder from any of the colorbox macros placed within any of the SlideshowItems.
So, there is my issue. Trying to only get the parameter SlideshowFolder from the individual colorbox macro that is inserted into that particular SlideshowItem.
I'll look over all of your suggestions and see if any of it will apply to my situation. Thanks for being patient.
this macro call is in the template of a page which is available via url like this:
mysite.org/tape/news?page=2&tag=somekeyword
I have to admit only one thing: the @queryStringName syntax works with not only GET querystring vars AFAIK, but with all REQUEST vars including POST vars and cookies.
To get and parse macro parameters in the Partial View Macro in 6.x we did simethig like this:
int total = 0, pageNum = 1, itemsPerPage = 10;
int.TryParse(Model.MacroParameters["totalCount"].ToString(), out total);
int.TryParse(Model.MacroParameters["itemsPerPage"].ToString(), out itemsPerPage);
int.TryParse(Model.MacroParameters["pageNum"].ToString(), out pageNum);
Some time ago I've even use this package, which adds the extension method to the Library class and gives the possibility of calling macro from another macro body.
UPDATE: this package was useful in times of 4.x :-) In 6.x partial view macros there is a out of the box way to call another macro via @Umbraco.RenderMacro("macroAlias", new { paramCollection })
Concerning the following proposals how to organize a macro calls from RTE, there is totally IMHO :-) but if there are no cases in the project where is no possibility to avoid macros in the RTE, I've tried not to use this approach AT ALL :-) The faith in "No any code parts where content editor walks" is still works like a charm ;-)
ahh dynamic node razor, so have a look at the attached screen grabs, I think I've setup the structure you describe...
What is the colorbox macro parameter ?
Now we implement the Colorbox Macro with a DynamicNode Razor file:
@inherits umbraco.MacroEngines.DynamicNodeContext
@{
var slideShowFolderId = Parameter.slideShowFolder;
// get slideShowFolder Umbraco Node
var slideShowFolder = Library.NodeById(slideShowFolderId);
}
<h2>@slideShowFolder.Name (@slideShowFolder.Id)</h2>
@* loop through the children to write out the slides *@
<ul>
@foreach( var node in slideShowFolder.Children()){
<li>@node.Name (@node.Id)</li>
}
</ul>
Hopefully you can see in theory, the macro gets a reference to the 'picked folder' via Parameter.slideShowFolder (which is the alias of the parameter created in the macro config)
We then use the Library.NodeById to get the parent Slide Show Folder node itself.
Then loop through the children, which are the SlideShowItems, and can write out the relevant properties within the relevant html for the slider:
Anyway even if this isn't the exact structure hopefully, gives you better clues, about how to do it than the Macro Partial View examples...
I've updated mine to pick from the Media folder too
and now have the following razor:
@inherits umbraco.MacroEngines.DynamicNodeContext
@* Get the parameter of the slideshow folder *@
@{
var slideShowFolderId = Parameter.slideShowFolder;
// get slideShowFolder Media folder
var slideShowFolder = Library.MediaById(slideShowFolderId);
}
<h2>@slideShowFolder.Name (@slideShowFolder.Id)</h2>
@* loop through the children to write out the slides *@
<ul>
@foreach( var node in slideShowFolder.Children()){
<li>@node.Name (@node.Id)
<img src="@node.Url()" style="width:80px" />
</li>
}
</ul>
Which writes out the following:
So you can see, two different 'media folders' have been picked, for each macro when added to the rich text editor and two different sets of images looped through from the relevant folders.
Might be worth just writing out just the picked folder ids in the html, to confirm they are different, ie the Parameter bit on your macro is working properly.
Could it be the slider javascript plugin itself is merging the two sets of slides together, because of their html ? rather than being a macro parameter problem ??
Yea, it looks like the invocation of the colorbox is what is the problem. Unless there is some way to have it distinguish between the different slide groups, it will always grab them all.
It has to reference the class "slideGroup", which will always contain all the slides from every instance of colorbox. If there were a way to have it generate a class dependent on the slideFolder selected, it could differentiate.
ahh a disappointing conclusion - but we've nailed reading parameters right !!
if you are embedding the <script that calls the colorbox function in the Macro could you not customise the slideGroup class to include the slideFolder parameter ?
or something similar ? I'm not too familiar with the plugin. but it seems you are binding an instance of it to all links with class slideGroup, so why not bind it to all links with class slideGroup-3 where 3 is the id of the media folder, would that avoid the clash ?
Okay, I can see that it is adding the different slideFolder Ids to each instance of the macro, but the variable that is used to trigger the gallery opening is not getting named the same, so it doesn't open. Here is the html output of the document ready function. It's not putting the Id in, only the name "slideFolder".
It writes the ID when it generates the list items, but not in the script tag before it where the variable for the gallery is defined. It's like it doesn't understand what @Parameter is and just removes it leaving "slideFolder".
Hmm, so if your macro is only just the code below, are you able to see the value passed by the parameter ?
@inherits umbraco.MacroEngines.DynamicNodeContext
@* Get the parameter of the slideshow folder *@
@{
var slideShowFolderId = Parameter.slideFolder;
// get slideShowFolder Media folder
var slideShowFolder = Library.MediaById(slideShowFolderId);
}
<h2>@slideShowFolder.Name (@slideShowFolder.Id)</h2>
<h3>Passed Parameter Value: @Parameter.slideFolder </h3>
Yes so I think it is where you are escaping quotes and using brackets to seperate your serverside razor script and the javascript syntax you are producing, try:
if you unzip and run the solution, the colorbox macro I have, appears to add the picked folder id in the correct places in the javascript variables (view the source of the page)
Using a Parameter from a DocType To Set Paramater for Macro in Template
I have a template with a lightbox macro inserted within the template #1. It has one parameter that I would like to set from the docType of a piece of content that the template #1 is using. Is this even possible?
Template #1 has a bxslider in which the docType of SlideshowItem exists. I am trying to be able to select on each SlideshowItem the media folder for a lightbox that corisponds to that slide within the bxslider.
Confusing? Any help?
Hi Steve
There is a special syntax for passing the value of a doctype property directly into a macro parameter.
So if your macro is called 'DisplayLightbox', and your Macro Parameter is setup with alias called 'mediaFolderId' and your doctype has a media picker property called 'SelectMediaFolder' then in your template you can pass this into your macro like so:
ie [#propertyAliasName] means take the macro parameter from the current doc type property with that alias.
You also have available:
[$propertyAliasName] that will look recursively up your content tree for a property with the alias to supply the macro with a value - useful for 'global properties'.
[@querystringName] to take the parameter from a querystring value
[%sessionKeyName] to take the parameter value from the session object.
you can also 'chain these' to look for say a querystring value first, and if it doesn't exist take the doc type value eg:
Which would look first for a querystring parameter called id, if not present look for the doctype property 'SelectMediaFolder' and if that wasn't present use the value 5!
Marc, First of all I am using Umbraco v 6.1.6, and couldn't place the line of code you posted without an assembly error. But...
What if I need to pass the docType parameter to a macro that isn't placed on the template, but rather inserted on a content item that is a docType "slideshowItem"?
The slideshowItem doesn't have a template, as it is just a holder (docType) for an image, caption and, I am hoping, the insert lightbox macro (within a rich text editor field).
This way I could potentially have multiple slides in a bxslider that each could launch their own lightbox when clicked.
Ok, Steve, so you have a normal page doctype
eg standardPage
which contains a 'rich text editor' property
within this you wish to insert a 'display Slide Show' Macro
At the point of insertion, the macro will have a parameter (type ContentPicker) to allow the editor to pick a node (single node) from somewhere in the content tree, of document type 'SlideShow', underneath this node, will be further nodes based on a 'SlideShowItem' doctype, ie one node for each slide.
So in your macro Partial view that implements your macro (are you using Partial Views or DynamicNode Razor ?) you should be able to read the picked content node id from the parameter using:
although this helper extension may not actually be available in Umbraco 6.1.6 ...
otherwise I think it was
in earlier versions.
With the Id of the picked 'slide show' content you could then use
to get a reference to the slide show node and it's properties, furthermore use
to get a list of the slides to loop through and write out the slideshow html.
Or do you mean the macro parameter contentPicker will just pick a single SlideShowItem node, in which case just read the picked Id, and the above to get a reference to that node's properties / slide image etc - for the lightbox.
Or do you mean the macro is just for positioning and the relevant slides are picked on the underlying standardPage doctype - if so in the macro partial view, you can read the properties of the underlying document type content via Model.Content.GetPropertyValue etc
Marc, I am using DynamicNode Razor not Partial View.
You can see what my page is here: http://www.rose-hulman.edu/
The slideshow on this page is a bxslider razor macro embedded within the homepage template. The macro pulls images and other parameters from a docType "SlideshowItem" into each slide for the bxslider macro.
Because each slide (SlideshowItem), does not have a template and that I would like to be able to have different colorbox (lightbox)'s for multiple SlideshowItems I had to make the colorbox macro place-able into a rich text area on the editor, but since the colorbox macro uses the same parameter of "SlideFolder" within it's macro, it will always use the last selected SlideFolder from any of the colorbox macros placed within any of the SlideshowItems.
So, there is my issue. Trying to only get the parameter SlideshowFolder from the individual colorbox macro that is inserted into that particular SlideshowItem.
I'll look over all of your suggestions and see if any of it will apply to my situation. Thanks for being patient.
Hi Steve!
Concerning Umbraco 6.X:
Here is an example of the call universal docs list macro (both $ and @ syntax usage btw):
@Umbraco.RenderMacro("[tapes]itemsList", new {listNode="", itemsPerPage="[$pageSize]", pageNum="[@page]", colSmall="0" , withPager="1" , filterTag="[@tag]" })
this macro call is in the template of a page which is available via url like this:
mysite.org/tape/news?page=2&tag=somekeyword
I have to admit only one thing: the @queryStringName syntax works with not only GET querystring vars AFAIK, but with all REQUEST vars including POST vars and cookies.
To get and parse macro parameters in the Partial View Macro in 6.x we did simethig like this:
int total = 0, pageNum = 1, itemsPerPage = 10; int.TryParse(Model.MacroParameters["totalCount"].ToString(), out total); int.TryParse(Model.MacroParameters["itemsPerPage"].ToString(), out itemsPerPage); int.TryParse(Model.MacroParameters["pageNum"].ToString(), out pageNum);
Some time ago I've even use this package, which adds the extension method to the Library class and gives the possibility of calling macro from another macro body.
UPDATE: this package was useful in times of 4.x :-) In 6.x partial view macros there is a out of the box way to call another macro via @Umbraco.RenderMacro("macroAlias", new { paramCollection })
Concerning the following proposals how to organize a macro calls from RTE, there is totally IMHO :-) but if there are no cases in the project where is no possibility to avoid macros in the RTE, I've tried not to use this approach AT ALL :-) The faith in "No any code parts where content editor walks" is still works like a charm ;-)
Hi Steve,
ahh dynamic node razor, so have a look at the attached screen grabs, I think I've setup the structure you describe...
What is the colorbox macro parameter ?
Now we implement the Colorbox Macro with a DynamicNode Razor file:
Hopefully you can see in theory, the macro gets a reference to the 'picked folder' via Parameter.slideShowFolder (which is the alias of the parameter created in the macro config)
We then use the Library.NodeById to get the parent Slide Show Folder node itself.
Then loop through the children, which are the SlideShowItems, and can write out the relevant properties within the relevant html for the slider:
Anyway even if this isn't the exact structure hopefully, gives you better clues, about how to do it than the Macro Partial View examples...
Very similar to what my structure is except I am pulling slides from the Media library, so It should work using :
But is doesn't unfortunately. It seems to be grouping all the slides together in both instances of the macro.
Hi Steve
I've updated mine to pick from the Media folder too
and now have the following razor:
Which writes out the following:
So you can see, two different 'media folders' have been picked, for each macro when added to the rich text editor and two different sets of images looped through from the relevant folders.
Might be worth just writing out just the picked folder ids in the html, to confirm they are different, ie the Parameter bit on your macro is working properly.
Could it be the slider javascript plugin itself is merging the two sets of slides together, because of their html ? rather than being a macro parameter problem ??
Yea, it looks like the invocation of the colorbox is what is the problem. Unless there is some way to have it distinguish between the different slide groups, it will always grab them all.
It has to reference the class "slideGroup", which will always contain all the slides from every instance of colorbox. If there were a way to have it generate a class dependent on the slideFolder selected, it could differentiate.
Hi Steve
ahh a disappointing conclusion - but we've nailed reading parameters right !!
if you are embedding the <script that calls the colorbox function in the Macro could you not customise the slideGroup class to include the slideFolder parameter ?
eg.
and
or something similar ? I'm not too familiar with the plugin. but it seems you are binding an instance of it to all links with class slideGroup, so why not bind it to all links with class slideGroup-3 where 3 is the id of the media folder, would that avoid the clash ?
I believe you've got something there Marc! I will play around with it and let you know. Thanks!
Rats! I can't get the script to load.
what's a sideFolder ?
you mean @Parameter.slideFolder... :-)
(you can also read that into a variable at the top to make it less cluttered)
Also what is the error ?
The var slideFolder at this point should be changed to "slideFolderLocation", but even after doing that, the script will not load.
Errors are turned off and I've tried to add a "try / catch", with no luck.
Hi Steve,
Try using @Html.Raw to write out the javascript variable:
also in your li you have
sideFolder instead of slideFolder
Okay, I can see that it is adding the different slideFolder Ids to each instance of the macro, but the variable that is used to trigger the gallery opening is not getting named the same, so it doesn't open. Here is the html output of the document ready function. It's not putting the Id in, only the name "slideFolder".
so close
Are you using Html.Raw to write out the javascript ?
and are you saying that Parameter.slideShowFolder is just being written out as with the text slideFolder rather than the Id ?
Correct.
What you see in my last post (the script tags) is directly copied from the source of the page after load.
Hi Steve
Do you want to repost your full macro code again, to see where we are up to ?
somehow Parameter.slideShow is not writing out the picked id, but it was earlier in the thread I think, which would make your variable unique.
cheers
Marc
It writes the ID when it generates the list items, but not in the script tag before it where the variable for the gallery is defined. It's like it doesn't understand what @Parameter is and just removes it leaving "slideFolder".
Here is where we are with the code:
When you are inside the @Html.Raw you don't need the @ on Parameter
I've tried it both ways and it still doesn't pull in the Parameter.
Hmm, so if your macro is only just the code below, are you able to see the value passed by the parameter ?
Yes, this area was never an issue, it the section with the Javascript here
Yes so I think it is where you are escaping quotes and using brackets to seperate your serverside razor script and the javascript syntax you are producing, try:
which for me produces the html for the script tag as:
where 1059 is the id of the folder passed as parameter
It still doesn't add the Id to the javascript. Gives me the exact same results as before.
The puzzle is for me is you get an Id of the picked folder sent via the parameter when you just write out:
<h1> @Parameter.slideFolder </h1>
but when you write it out inside the script tag eg
@Html.Raw("var $gallery_" + Parameter.slideFolder + ...
you get the text 'slideFolder' instead of the Id ?
Also is the parameter on the macro called 'slideShowFolder' or 'slideFolder'
Can't help feeling we're on the cusp of it working!!
Yes, it is a puzzle. Very frustrating! It should bring in the id for slideShowFolder in the javascript as well, but it doesn't.
And sorry for the confusion, the parameter has been both slideFolder and slideShowFolder. Right now the macro has "slideShowFolder" as the parameter.
HI Steve
Here is a zip of my solution:
https://www.dropbox.com/s/y4zqqozjvz2a0kj/Umbraco616.zip?dl=0
if you unzip and run the solution, the colorbox macro I have, appears to add the picked folder id in the correct places in the javascript variables (view the source of the page)
regards
Marc
is working on a reply...