Getting Related Fields in Widget

132 views
Skip to first unread message

Bryce

unread,
Feb 26, 2020, 4:21:42 PM2/26/20
to dotCMS User Group
I have created a widget and added a related field to grab data for the widget. Is there a way to retrieve that data in the related field in the Widget Code. I have tried many different techniques that are documented on the DotCMS website including: 

1. Pulling data using pullRelatedField https://dotcms.com/docs/latest/pull-and-display-related-content 

It seems that when using a widget the $identifier variable is empty for the widget content. This is resulting in a null pull coming from the pullRelatedField call.

2. Pulling data using the methodology in Content Page content.  https://dotcms.com/docs/latest/content-object-in-velocity

The relationship that was created in the widget was a One to One mapping. Based on the documentation it was assumed the relationship field data could be pulled using 

$relationshipFieldVar.fieldName

but this is not the case. When printing out $relationshipFieldVar variable it returns a ContentletRelationships object, but I cannot see how the functions or the properties can be accessed to pull the data.

If anyone has any ideas that would be helpful. 

Nollymar Longa

unread,
Feb 27, 2020, 9:11:22 AM2/27/20
to dotCMS User Group
Hi Bryce, 

Using the ContentletRelationships object you can call the getRelationshipsRecords() method which returns a list of ContentletRelationshipRecords. Each record contains a Relationship object and a list of Contentlets. Please take a look at the class for more details https://github.com/dotCMS/core/blob/master/dotCMS/src/main/java/com/dotmarketing/portlets/structure/model/ContentletRelationships.java. Hope this helps,

Nollymar

Bryce

unread,
Feb 27, 2020, 9:17:20 AM2/27/20
to dotCMS User Group
I'm actually trying to use the relationship field inside a velocity template. For instance, I have a content type named Blog Post and I also have a content type that is an author. The simple relationship setup is that each blog post has a single Author. A one to one relationship. 

In my container or Widget Code I've been trying to map the content and print the name of the author on the page. Unfortunately, accessing the Author directly doesn't seem to give an data. 

<div>$author.name</div> 
<div>$author.location</div> 

What I do get when I print out $author is a something like this com.dotmarketing.portlets.structure.model.ContentletRelationships@4f87fb2e

I'm not sure how to actually access this data in the container or widget code. The documentation provided only specifies the ability to pull the data given the identifier of the content but even within the container or widget code print $identifier gives nothing.

Chris Falzone

unread,
Feb 27, 2020, 9:55:12 AM2/27/20
to dotCMS User Group
So, it's sort of a hacky work-around .. I think we also ran into issues with pulling relationships in widgets.  We eventually moved to an approach that only uses normal content and not widgets.  But I think this would work:

#set($theWidgetContent = $dotcontent.find(--the-inode-of-the-widget--))

I can't off the top of my head remember what the variable name for the content's inode is, but it is available.  This little chunk pulls the ContentMap of the content, which has all the convenience methods for working with the relationships.  

Another trick you can do is print out the $context variable, this would tell you all of the variables available in the current page's context.  I believe this really old chunk of code from Michael still works to display the context:
https://dotcms.com/codeshare/getting-the-page-context-values

Hope that helps! 

Chris Falzone

unread,
Feb 27, 2020, 10:15:53 AM2/27/20
to dotCMS User Group
FWIW, what Nollymar was saying is true for velocity as well as Java, velocity just executes the java class behind it.

$authors gives you the ContentletRelationships object.
$authors.getRelationshipsRecords() returns a list of ContentletRelationshipRecords which you can loop over with #foreach
The items in that list then have a .getRecords() method that allows you to get a list of Contentlet objects in the relationship.

That being said, a Contentlet is not the same thing that the $dotcontent tooling returns (ContentMap) which is what you want in velocity. This is why I suggest to use $dotcontent.find on the widget's identifier to get the widget's ContentMap and then the methods you are referring to in the docs to work with relationships will work.  It would be the same thing if you are in container code instead of widget code.

Hope that helps explain it a little further.

On Wednesday, February 26, 2020 at 4:21:42 PM UTC-5, Bryce wrote:

Bryce

unread,
Feb 27, 2020, 10:35:13 AM2/27/20
to dotCMS User Group
Thanks. This helped immensely. I'm not much of a Java developer and just started out using Apache Velocity but your explanation provided enough information for me to figure it out. I'm now able to retrieve related information from my Widget. 

Mark Orciuch

unread,
Apr 21, 2021, 2:30:17 PM4/21/21
to dotCMS User Group
Hello Chris,

I am also having an issue retrieving related content in a widget. Something like $relationvariable.getRelationshipsRecords() does not work at all in a widget.

In your post, you suggest using #set($theWidgetContent = $dotcontent.find(--the-inode-of-the-widget--)) to retrieve the widget content. What is the name of variable holding the widget's inode? Many thanks in advance.

Falzone, Chris

unread,
Apr 22, 2021, 7:46:16 AM4/22/21
to dot...@googlegroups.com
In widgets they are just exposed to the context.  I never remember the exact variables. It's either like $CONTENT_INODE or $contentInode or either pattern with contentlet spelled out.  

Sometimes this little ditty is helpful, it spits out everything in the context so you can see what it is ...

<ul>
#foreach($key in $context.getKeys())
  <li><strong>${key} :</strong> ${context.get($key)}</li>
#end
</ul>



--
http://dotcms.com - Open Source Java Content Management
---
You received this message because you are subscribed to the Google Groups "dotCMS User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dotcms+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dotcms/19844d15-f376-4b48-9174-5b5447c928ddn%40googlegroups.com.


--

Christopher Falzone

DevOps Engineer

A Q U E N T  /  VITAMIN T

Mark Orciuch

unread,
Apr 22, 2021, 11:14:15 AM4/22/21
to dotCMS User Group
Hi Chris,

Thanks for the trick on displaying the velocity context. Unfortunately, the widget's identifier is nowhere to be found in the context. I ended up using this hack to get what I want:

#foreach($widget in $dotcontent.pull("+structureName:AuditorFormWidget",0,""))
    #if($widget.formType.selectValue == $formType)
        dataObj.notificationEmail = "+identifier: $widget.notificationUser.get(0).identifier";
    #end
#end

I encountered the same issue with a workflow - the related fields are not being populated as well. Thanks again.

Mark Pitely

unread,
Sep 16, 2021, 11:54:06 AM9/16/21
to dot...@googlegroups.com
Hey, I ran into this problem myself today. Thanks, all, for spelling out all the issues and solutions.
Unsurprisingly, Chris was right - the field is there, but it took some serious searching to find it:
$contentletId is the identifier of the widget instance.
Also, note that this is useful if you need to get at the values and options of a Select or Multiselect, which are also 'crippled' in Widget/Container code. (calls to such a field return the selectedValue)
That is - $myselect would simply return 'yes' (which IS helpful most of the time), instead of referencing the normal $myselect.selectedValue.

Some code that shows this in action:


<div class="page-section">
<h2>$!title</h2>
$!copy
<div class="block-accordion-set">

#set ($puller=$dotcontent.find($contentletId))
##Now we have the widget as if it was in a normal velocity context, rather than in the Widget Context.
##E.g. $title above works, but it is also $puller.title, and we can extract the relationships properly.
#set ($accordions=$puller.accordionEntry)

#foreach ($accordion in $accordions)
                        <div class="accordion">
                            <input id="accordion-${velocityCount}" type="checkbox" class="hidden-check">
                            <label for="accordion-${velocityCount}">$accordion.heading</label>
                            <div class="expander-content">
                                <div class="expander-scroll">
                                    <div class="section">
                                        $accordion.copy
                                    </div>
                                </div>
                            </div>
                        </div>
#end
                       
</div>
</div>



Mark Pitely
Marywood University






Reply all
Reply to author
Forward
0 new messages