I have been trying to get an auto slot to populate from the contents of a sys_DropDownMultiple control. I know this would be far easier to just use a manual slot and only allow a certain content type in the slot, however I have a situation where many items would need to be added to the slot and for speed it would be better to select them from a list rather than searching for each one.
My first idea was to create a dynamic WHERE clause and pass it to the sql query in the auto slot but this does not seem to work since the parameters of the auto slot must be in URL query format, so passing something like “rx:sys_contentid=1847 OR rx:sys_contentid=1858 OR rx:sys_contentid=1869” is not possible.
I can get the process to work by looping over the value contained by the sys_DropDownMultiple control (content id of selected content type) and creating multiple slots but this has disadvantages such as not being able to sort or group the items.
The sys_AutoSlotContentFinder allows you to pass in a parameter called query. So you could use some kind of loop to build up a JSR-170 query* in a string variable called $query, then call the #slot macro (or #initslot if doing a “raw slot”) like this:
This approach will work, but you should use the Map form rather than the String form as described in my previous post. Otherwise the spaces and punctuation in $query will need to be escaped first.
When I attempt to use the Map form I receive the error “Problem assembling output for item: 1-101-1944 with template: erauPgWWCenter exception: unexpected token: rx:sys_contentid see log for stack trace”. The console log doesn’t give any other clues to the problem, has anyone else used the IN operator within a slot?
Slot query:
SELECT rx:degree_name, rx:degree_type, rx:temp_web FROM rx:erauDegreeProgram WHERE rx:sys_contentid IN (:ids) Order by rx:degree_name
When I modify the slot query to use a standard = operator and only a single slotparam I can’t get a result either. “Problem assembling output for item: 1-101-1944 with template: erauPgWWCenter exception: parameter ids not defined see log for stack trace”.
SELECT rx:degree_name, rx:degree_type, rx:temp_web FROM rx:erauDegreeProgram WHERE rx:sys_contentid = :ids Order by rx:degree_name
Lastly, I tried just using the IN operator without passing any parameters and could not receive a result. (same error as before)
SELECT rx:degree_name, rx:degree_type, rx:temp_web FROM rx:erauDegreeProgram WHERE rx:sys_contentid IN ('1947,1948') Order by rx:degree_name
I could get a result with a simple = operator and without any params.
SELECT rx:degree_name, rx:degree_type, rx:temp_web FROM rx:erauDegreeProgram WHERE rx:sys_contentid = '1947' Order by rx:degree_name
It turns out I was wrong, we don’t support “IN” in JCR Queries (and the JCR spec does not require this support, either). (Bad news for those of you who thought I knew everything, I suppose).
I used the $user.psoStringTools.getStringBuilder() method to build the query. I suppose that you could do this with ordinary concatenation, but this way looks better (and will run faster).
Assuming some basics are defined in the bindings, the Velocity code looks like this:
Thanks for your help so far, logically everything makes sense but I am still running into trouble with passing the map variable. Could you show what bind variables are needed (if any) to pass the map variable? It appears that my JSR-170 query does not recognize the map variable, “Problem assembling output for item: 1-101-1944 with template: erauPgWWCenter exception: unexpected token: :wclause see log for stack trace”
When I looked in the System Velocity Macro definition for the slot I noticed the variable was called $params, not $slotparams so I tried changing all references to this but I am still getting the same error.
erauDegreeList slot parameters:
Type: Regular
Allowed Relationship Types: Active Assembly
Content finder: sys_AutoSlotContentFinder
You cannot define the whole “where clause” as a single substitution variable. You can only define the right hand side of an expression.
Go back and look at my example earlier in this thread. You will notice that I build the ENTIRE query in the query builder and pass it to $slotparams.query. This is the only way that it will work.
I really don’t think it is passing the map variable correctly, now I am getting “Problem assembling output for item: 1-101-1944 with template: erauPgWWCenter exception: expecting “select”, found ‘:myquery’ see log for stack trace”
Slot with binding set to $slotparams.myquery = “”:
#set($myChildren = $sys.item.getProperty("degrees").getValues())
#set($qrybldr = $user.psoStringTools.getStringBuilder("select rx:degree_name, rx:degree_type, rx:temp_web FROM rx:erauDegreeProgram where "))
#set($operator = "")
#foreach($myChild in $myChildren)
#set($nop1 = $qrybldr.append($operator))
#set($nop2 = $qrybldr.append("rx:sys_contentid = "))
#set($nop3 = $qrybldr.append($myChild.String))
#set($nop4 = $qrybldr.append(" "))
#set($operator = " or ")
#end
#set($nop5 = $qrybldr.append(" order by rx:degree_name"))
#set($slotparams.myquery = $qrybldr.toString())
#slot("erauDegreeList" "" "" "" "" $slotparams)
I believe that the problem is where you define $slotparams.myquery
#set($slotparams.myquery = $qrybldr.toString())
it should probably be:
#set($slotparams.query = $qrybldr.toString())
as i believe the query and template “values”/“names” are specific and the slot looks for those specifically.
Note: In order for me to get this to work, i had to specify blank values for $slotparams.query and $slotparams.template in the bindings tab of the template as for some reason velocity wasn’t / isn’t creating new objects (see http://forum.percussion.com/showthread.php?t=864). The blank values in the bindings initialize the map, creating the objects.
PS. Thanks Dave, this saves me from creating a large number of slots (ie, sort ascending vs descending)
Changing all references from “myquery” to “query” initially did not have an effect, but adding a $slotparams.template variable caused the error to change to “Problem assembling output for item: 1-101-1944 with template: erauPgWWCenter exception: query is a required argument see log for stack trace”.
i believe the query and template “values”/“names” are specific and the slot looks for those specifically.
This is correct, the parameters need to be named “query” and “template”, and as Jit suggests, you need Bindings for these.
It should not matter that you have a Query defined in the slot definition, as the query will be overriden by the one in the slot parameters.
I know that the Fast Forward autoindices select slots rather than building queries, but this approach (building the query on the fly) is probably simpler to understand, and it can potentially save you from creating lots of extra slots.
Ok I am getting some results now, I had to:
[ul]
[li]remove the $user.psoStringTools.getStringBuilder() method and just use a simple #set($qrybldr="") statement.
[/li][li]remove the .append() method for concatenation… is there another way to do this, I have tried using + signs but this isn’t working?
[/li][/ul]
(leaving/removing the :query map variable in the slot query produced the same results)
I don’t have a :query variable in the query, just in the query placeholder of the slot (the map variable reference). I have tried passing a complete query with and without having this value present and the query passes the same way. (see attached photo of the erauDegreeList slot).
The only part I can’t get to work is the alternative string concatenation.
Thanks to Dave and jitendra for their help with this issue, I think everything is functioning correctly now, for those of you interested in the final version: