How to select multiple dexterity elements of one type in one dexterity element of another type in Plone 5.1

Hello,

I have created TTW two types of dexterity content and would like to be able to multi select elements of one type in the elements of the other type.

For instance:
1.- My first dexterity is Room and my second dexterity is Book.
2.- I have created several rooms and several books.
3.- In each room I would like to be able to select one or more of the existing books.

How could I do this?

Thanks!

Manuel

See the code snippets in this answer: Use case for a listing component - #4 by tiberiuichim

I understand that this option requires exporting the content type dexterity Room and adding the codes manually, in its file system. Correct? (so far I have always worked with dexterity TTW).

Thanks!

Manuel

Yes. See training docs 19. Write Your Own Python Add-On to Customize Plone โ€” Plone Training 2021 documentation

I'll try to follow your advice: follow step 19.1, 19.5 in the linked page, then chapters 20, 21.

Thanks!

Achieved!

\ :wink:

But I can't display the selected books in the room view.

How could I do it in Plone 5.1.6?

Thanks!

Manuel

PS:

<span tal:replace="structure context/books" /> displays "[, ]"

<span tal:content="context/books" /> displays "[<z3c.relationfield.relation.RelationValue object at 0x7f13606af650>, <z3c.relationfield.relation.RelationValue object at 0x7f13606af550>]"

Other things give errors.

After pin:
plone.app.z3cform = 3.2.0
plone.app.widgets = 3.0.0

<div tal:content="structure view/w/books/render" /> give error "LocationError: (<Products.Five.metaclass.Plone object at 0x7f135ae20150>, 'w')".

<span tal:replace="structure python: view.w['books'].render()"/ > give error "AttributeError: 'Plone' object has no attribute 'w'".

Start with the version of code that gives you this:

<span tal:content="context/books" /> displays "[<z3c.relationfield.relation.RelationValue object at 0x7f13606af650>, <z3c.relationfield.relation.RelationValue object at 0x7f13606af550>]"

It's good, you're almost there. Now you have to "resolve" those RelationValue to the linked object. You can do like:

<ul>
<li tal:repeat="rel python: context.books or []">
<a tal:define="obj python: rel.to_object" tal:attributes="href obj/absolute_url" tal:content="obj/Title">Book title</a></li>
</ul>

I hope my code is not wrong, but don't take it as 100% bulletproof.

(I presume that you've followed this? 43. Relations โ€” Plone Training 2021 documentation Seems like a good chapter)

Your code is OK.

Thank you very much!

:smiley:

Now, I will try to display the images...

And yes, I read 43. Relations โ€” Plone Training 2021 documentation (and many other pages ...).

When I finish, I will post everything I have done here, in case it helps other beginners ...

Regards

My joy in a well !!

Only works for Managers: anonymous visitors get an LocationError.

:frowning:

I'm going to study it ...

The above code is OK for Managers and Site Administrators.

But not for other users: if one related book is not published, they can't view the room (login request for not logged users and insufficient privileges error for logged users).

I can "solve" this problem with a huge block of code:

\<div tal:define="is_manager python:test(here.portal_membership.getAuthenticatedMember().has_role('Manager'), 1, 0);
                 is_site_administrator python:test(here.portal_membership.getAuthenticatedMember().has_role('Site Administrator'), 1, 0);
                 is_not_manager python:test(here.portal_membership.getAuthenticatedMember().has_role('Manager'), 0, 1);
                 is_not_site_administrator python:test(here.portal_membership.getAuthenticatedMember().has_role('Site Administrator'), 0, 1)"\>

  \<div tal:condition="python:is_manager or is_site_administrator"\>
    \<div tal:repeat="rel python: context.books or []"\>
      \<p\>
        \<a tal:define="obj python: rel.to_object" tal:attributes="href obj/absolute_url"\>
          \<img tal:attributes="src string:${obj/absolute_url}/@@images/image/thumb;title obj/Title;alt obj/Title" /\>
        \</a\>
      \</p\>
      \<p\>
        \<a tal:define="obj python: rel.to_object" tal:attributes="href obj/absolute_url;title obj/Title" tal:content="obj/Title" /\>
      \</p\>
    \</div\>
  \</div\>

  \<div tal:condition="python:is_not_manager and is_not_site_administrator"\>
    \<div tal:repeat="rel python: context.books or []"\>
      \<p\>
        \<a tal:define="obj python: rel.to_object;review_state obj/@@plone_context_state/workflow_state;published python:review_state == 'published'" tal:condition="published" tal:attributes="href obj/absolute_url"\>
          \<img tal:attributes="src string:${obj/absolute_url}/@@images/image/thumb;title obj/Title;alt obj/Title" /\>
        \</a\>
      \</p\>
      \<p\>
        \<a tal:define="obj python: rel.to_object;review_state obj/@@plone_context_state/workflow_state;published python:review_state == 'published'" tal:condition="published" tal:attributes="href obj/absolute_url;title obj/Title" tal:content="obj/Title" /\>
      \</p\>
    \</div\>
  \</div\>

\</div\>

This works, but I imagine there will be a better (shorter and more elegant) solution for Plone 5.1.6...

Sorry!

Are you using a TTW page template? I think the template registered via a ZCML declaration (optionally together with a Python class) shouldn't hit this problem. Basically Browser Views. Views โ€” Plone Documentation v5.2

Yes, so far I have used a TTW page template.

The next thing is to try to do what you recommend.

Thanks!

Achieved, although I have to specify the .pt template name in configure.zcml (if I don't, I just get <Products.Five.metaclass.ActividadView object at 0x7ffad195b510> results).

Now, the above code:

<ul>
<li tal:repeat="rel python: context.books or []">
<a tal:define="obj python: rel.to_object" tal:attributes="href obj/absolute_url" tal:content="obj/Title">Book title</a></li>
</ul>

displays all related items to all visitors, even if there are private related items.

It is an improvement, but I think I will continue to use the long code that does not show the private related items to those who do not have permission to see them.

Now I will study how to add the fields programmatically and how to automatically set the views to the content types ...

Thanks!

Unless I am missing something: You can add this functionality TTW in the Dexterity Control panel. Add a field of type "RelationList"

Yes, you are right: I can do it and it works perfectly.

So really, I didn't need to create the add-on and content types with plonecli: I can do it all TTW.

Although, I have learned very interesting things.

:slight_smile:

Thanks!

If a book has been selected as a related item in multiple rooms, how could I automatically show this on book page? (that the book page shows, linked, the rooms in which it has been selected)

The following doesn't work for me (the search shows all rooms, not just those related to the particular book):
tal:define="rooms python:context.portal_catalog.searchResults(portal_type='my_room', related_books=('book1'))"

And also I have not been able to set a condition based on the Relation List (see ?????????):

  <tal:roomsitem tal:repeat="roomsitem rooms">
  <p>
    <a tal:define="book_id context/id;room_related_books ?????????" tal:condition="python:book_id in room_related_books"
       href=""
       tal:attributes="href roomsitem/getURL; title roomsitem/Description"
       tal:content="roomsitem/Title">Room</a>
  </p>
  </tal:roomsitem>

Thanks!

Manuel

Let's assume that you have the Room which defines that it can relate to multiple Books. This would be the "forward relationship". The Book automatically gets a "backward relationship" to the Room that links it. I think it would be backrelations(obj, attribute=None, as_dict=False)
from the collective.relationhelpers ยท PyPI and it would probably be called like rooms = backrelations(my_context_book, 'books_or_whatever_the_relation_name_is')

I have managed to install collective.relationhelpers in Plone 5.1.6:

[buildout]
eggs =
    collective.relationhelpers==1.4

[versions]
plone.restapi = 7.3.5
PyJWT = 1.7.1
plone.schema = 1.2.1

I will try to do what you tell me (it won't be easy for me ...).

Thanks,

Manuel

I think I had something similar, so in case it is of any relevance, I share the link:

Thanks, Espen,

I have been searching for "Plone backrelation" for several days and I had not found anything that could serve as a reference on what the code to include in the template of my books should be like.

About your code:

1.- Would I need to create a add-on with plonecli or could it be TTW in some way (creating some kind of file in the ZMI and calling it from the books template)?

2.- If I need to create a add-on with plonecli:

2.1.- In which file should the get_relateditems code be added?

2.2.- Could it be customized so that it only shows the related items of my RelationList?

2.3.- Would the Room and Book content types also have to be created with plonecli in the plugin or could be created TTW? And the templates?

Sorry for so many questions and ignorance ...

Thanks!

Manuel

Plone Foundation Code of Conduct