linkField with jcrDatasource - filter nodes in chooser ?

52 views
Skip to first unread message

Marc “Marc J” Johnen

unread,
Jul 3, 2024, 2:55:12 PMJul 3
to Magnolia User Mailing List
Hi everyone,

I would like to filter the pages offered in the chooser of a linkField (using jcrDatasource) by the template of the pages (mgnl:template). Currently jcrDatasource only seems to offer a filter for allowedNodeTypes. jcrDatasource is not exactly easily extendable.

The only thing I managed is to configure a custom chooser where I added a column "mgnl:template" and set the defaultValue to 'my:pages/shared'. The filter works, I might be able to hider the column, but I need the filter to allow two different template. Also the presenter shows a list not a tree when a column filter is active, I would need a tree view.

Is there some way to achieve my goal? Am I missing something?

Thanks
Marc Johnen



my component.yaml:

label: Content Block

light: false

form:

$type: tabbedForm

tabs:

content:

label: Static content

fields:

link:

$type: linkField

chooserId: my-module:chooser

label: Inhalt

datasource:

$type: jcr

workspace: website

allowedNodeTypes:

- mgnl:page

describeByProperty: title


I added a custom chooser:

class: info.magnolia.ui.chooser.definition.SingleItemWorkbenchChooserDefinition

actions:

choose:

class: info.magnolia.ui.contentapp.action.ChooseActionDefinition

cancel:

$type: closeAction


workbenchChooser:

workbench:

extensionViews:

- name: fullTextSearch

class: info.magnolia.ui.chooser.definition.FullTextSearchExtensionViewDefinition

contentViews:

- name: tree

multiSelect: false

$type: treeView

readOnly: true

columns:

jcrName: &jcrNameColumn

$type: jcrTitleColumn

icon: icon-node-content

nodeTypeToIcon:

mgnl:folder: icon-folder

mgnl:page: icon-webpages-app

mgnl:category: icon-categories

mgnl:contact: icon-people

mgnl:persona: icon-persona

mgnl:segment: icon-segment

title: &titleColumn

$type: configuredColumn

label: Titel

filterComponent:

$type: textField

defaultValue: ''

converterClass: info.magnolia.ui.editor.converter.StartsWithFilteringModeConverter`

mgnl:template: &templateColumn

$type: configuredColumn

label: Template

filterComponent:

$type: textField

defaultValue: 'my:pages/shared'

converterClass: info.magnolia.ui.editor.converter.StartsWithFilteringModeConverter`

- name: list

multiSelect: false

$type: listView

readOnly: true

columns:

jcrName: *jcrNameColumn

jcrPath:

$type: jcrPathColumn

mgnl:template: *templateColumn

Roman Kovařík

unread,
Jul 4, 2024, 4:09:22 AMJul 4
to Magnolia User Mailing List, 108m...@googlemail.com
Hi Marc,

You should be able to customise the data provider, e.g:

public class MyHierarchicalJcrDataProvider extends HierarchicalJcrDataProvider {

    @Inject
    public MyHierarchicalJcrDataProvider(JcrDatasourceDefinition definition, JcrDatasource datasource) {
        super(definition, datasource);
    }

    @Override
    protected Stream<Item> fetchChildrenFromBackEnd(HierarchicalQuery<Item, DataFilter> query) {
        query = new HierarchicalQuery<>(query.getFilter().orElse(null), query.getParent());
        return super.fetchChildrenFromBackEnd(query)
                .filter(item -> filterTemplate((Node) item));
    }

    private static boolean filterTemplate(Node item) {
        try {
            return !"travel-demo:pages/standard".equals(NodeTypes.Renderable.getTemplate(item));
        } catch (RepositoryException e) {
            throw new RuntimeException(e);
        }
    }
}


And add the mapping to your module descriptor:


<components>
  <id>datasource-jcr</id>
  <type-mapping>
    <type>info.magnolia.ui.contentapp.HierarchicalJcrDataProvider</type>
    <implementation>info.magnolia.ui.contentapp.MyHierarchicalJcrDataProvider</implementation>
  </type-mapping>
</components>

You can also extend the JcrDatasourceDefinition, so the templates would be configurable.

Hope that helps
Roman

Marc “Marc J” Johnen

unread,
Jul 4, 2024, 6:51:05 AMJul 4
to Magnolia User Mailing List, Roman Kovařík, 108m...@googlemail.com
Thanks a lot Roman. This was much easier than I thought.
You do need a custom JcrDatasourceDefinition, otherwhise the changes will also effect other Views like the pages app.

Roman Kovařík

unread,
Jul 4, 2024, 7:11:13 AMJul 4
to Magnolia User Mailing List, 108m...@googlemail.com, Roman Kovařík

You're right. Just be careful to not inject the custom definition class directly, the other places would create an empty instance of such definition. You need to still inject the JcrDatasourceDefinition class and cast later.

Marc “Marc J” Johnen

unread,
Jul 4, 2024, 10:37:31 AMJul 4
to Magnolia User Mailing List, Roman Kovařík, 108m...@googlemail.com
Yes, that's exactly what I did. Thanks again.
Reply all
Reply to author
Forward
0 new messages