Skip to content

Commit

Permalink
Merge pull request #136 from syslabcom/scrum-1181-publicationlisting
Browse files Browse the repository at this point in the history
Port publicationlisting viewlet
  • Loading branch information
reinhardt authored Jan 5, 2024
2 parents 03ec136 + 4a897e6 commit beb9e22
Show file tree
Hide file tree
Showing 3 changed files with 299 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/recensio/plone/viewlets/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,12 @@
layer="recensio.plone.interfaces.IRecensioPloneLayer"
/>

<browser:viewlet
name="publicationlisting"
manager="plone.app.layout.viewlets.interfaces.IBelowContent"
class=".viewlets.Publicationlisting"
template="templates/publicationlisting.pt"
permission="zope2.View"
/>

</configure>
138 changes: 138 additions & 0 deletions src/recensio/plone/viewlets/templates/publicationlisting.pt
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<div id="publicationlisting"
tal:define="
language context/@@plone_portal_state/language;
portal_url context/portal_url;
"
tal:condition="view/visible"
i18n:domain="recensio"
>

<a name="publicationslisting"></a>
<tal:volumes repeat="volume view/volumes | nothing">
<div class="review_container"
tal:define="
volume_expanded python:view.is_expanded(volume['UID']);
is_container python:volume['css_classes'] and 'review_container' in volume['css_classes'];
"
tal:attributes="
id volume/UID;
class volume/css_classes;
"
>
<a class="container_trigger"
href="#"
tal:condition="is_container"
tal:attributes="
href volume/toggle_link;
"
>
<h2 tal:content="volume/Title"></h2>
</a>
<h2 tal:condition="not:is_container"
tal:content="volume/Title"
></h2>

<span class="pdf"
tal:condition="volume/pdf | nothing"
>
<a href=""
tal:attributes="
href string:${volume/pdf}/at_download/file;
"
>
<img alt=""
src="pdf.png"
/>&nbsp;
<span i18n:translate="label_download_complete_pdf">download Gesamt-pdf</span>
</a>
<span class="discreet">
&mdash;
<span>PDF</span>,
<tal:size content="volume/pdfsize">?</tal:size>
</span>
</span>

<ul tal:condition="is_container">
<li tal:condition="volume_expanded"
tal:repeat="review python:view.reviews(volume=volume['id'])"
>
<a tal:content="review/getDecoratedTitle"
tal:attributes="
href review/absolute_url;
"
></a>
</li>
</ul>
</div>

<tal:issues repeat="issue python:view.issues(volume=volume['id'])">
<div class="review_container"
tal:define="
issue_expanded python:view.is_expanded(issue['UID']);
is_container python:issue['css_classes'] and 'review_container' in issue['css_classes'];
"
tal:attributes="
id issue/UID;
class issue/css_classes;
"
>
<a class="container_trigger"
href="#"
tal:condition="is_container"
tal:attributes="
href issue/toggle_link;
"
>
<h3 tal:content="issue/Title"></h3>
</a>
<h3 tal:condition="not:is_container"
tal:content="issue/Title"
></h3>


<span class="pdf"
tal:condition="issue/pdf | nothing"
>
<a href=""
tal:attributes="
href string:${issue/pdf}/at_download/file;
"
>
<img alt=""
src="pdf.png"
/>&nbsp;
<span i18n:translate="label_download_complete_pdf">download Gesamt-pdf</span>
</a>
<span class="discreet">
&mdash;
<span>PDF</span>,
<tal:size content="issue/pdfsize">?</tal:size>
</span>
</span>

<tal:comment replace="nothing">
An image would be nicer, but not my expertise :(
<img class="loading"
src="++resource++recensio.theme.images/fancy_loading.png"
tal:condition="is_container"
tal:attributes="
src string:${context/portal_url}/++resource++recensio.theme.images/fancy_loading.png;
"
/>&nbsp;
</tal:comment>
<ul tal:condition="is_container">
<li tal:condition="issue_expanded"
tal:repeat="review python:view.reviews(volume=volume['id'],issue=issue['id'])"
>
<a tal:content="review/getDecoratedTitle"
tal:attributes="
href review/absolute_url;
"
></a>
</li>
</ul>
</div>
</tal:issues>
</tal:volumes>

</div>
153 changes: 153 additions & 0 deletions src/recensio/plone/viewlets/viewlets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
from DateTime import DateTime
from plone import api
from plone.app.layout.viewlets import ViewletBase
from plone.memoize import ram
from Products.CMFCore.utils import getToolByName
from recensio.plone.adapter.indexer import listAuthorsAndEditors
from zope.interface import implementer
from zope.viewlet.interfaces import IViewlet
from ZTUtils import make_query

import logging


log = logging.getLogger(__name__)


def _render_cachekey(method, self, volume, issue=None):
portal_membership = getToolByName(self.context, "portal_membership")
member = portal_membership.getAuthenticatedMember()
roles = member.getRolesInContext(self.context)
today = DateTime().strftime("%Y-%m-%d")
context_url = self.context.absolute_url()
return (context_url, roles, today, volume, issue)


@implementer(IViewlet)
class Publicationlisting(ViewletBase):
"""Lists Volumes/Issues/Reviews in the current Publication"""

def __init__(self, context, request, view, manager=None):
super().__init__(context, request, view, manager)
try:
parents = self.request.PARENTS
except AttributeError:
return False
if len(parents) < 2:
return False
self.parent = self.request.PARENTS[1]

def visible(self):
"""should we display at all?"""
if (
hasattr(self.context, "portal_type")
and self.context.portal_type == "Document"
and hasattr(self.parent, "portal_type")
and self.parent.portal_type == "Publication"
):
return True
return False

def is_expanded(self, uid):
return uid in self.request.get("expand", [])

def _make_dict(self, obj):
"contains the relevant details for listing a Review"
view = api.content.get_view(
context=obj, request=self.request, name="review_view"
)
return {
"absolute_url": obj.absolute_url(),
"effective": obj.effective(),
"getDecoratedTitle": view.getDecoratedTitle(),
"listAuthorsAndEditors": listAuthorsAndEditors(obj)(),
"Title": obj.Title(),
}

def _get_toggle_link(self, uid):
expand = self.request.get("expand", [])[:]
if uid in expand:
expand.remove(uid)
else:
expand.append(uid)
toggle_link = "{}?{}#{}".format(
self.context.absolute_url(),
make_query(expand=expand),
uid,
)
return toggle_link

def _get_css_classes(self, obj):
css_classes = []
reviews = [
obj
for obj in obj.objectValues()
if obj.portal_type in ("Review Monograph", "Review Journal")
]
if len(reviews) > 0:
css_classes.append("review_container")
if self.is_expanded(obj.UID()):
css_classes.append("expanded")
return " ".join(css_classes) or None

def _make_iss_or_vol_dict(self, obj):
issue_dict = {
"Title": obj.Title(),
"id": obj.getId(),
"UID": obj.UID(),
"toggle_link": self._get_toggle_link(obj.UID()),
"css_classes": self._get_css_classes(obj),
}

if "issue.pdf" in obj.objectIds():
issue_dict["pdf"] = obj["issue.pdf"].absolute_url_path()
issue_dict["pdfsize"] = self._formatsize(obj["issue.pdf"].file.size)
return issue_dict

def volumes(self):
objects = self.parent.getFolderContents(
{"portal_type": "Volume"}, full_objects=True
)
volume_objs = sorted(objects, key=lambda v: v.effective(), reverse=True)
volumes = [self._make_iss_or_vol_dict(v) for v in volume_objs]
return volumes

def issues(self, volume):
if volume not in self.parent:
return []
objects = self.parent[volume].getFolderContents(
{"portal_type": "Issue"}, full_objects=True
)
issue_objs = sorted(objects, key=lambda v: v.effective(), reverse=True)
issues = [self._make_iss_or_vol_dict(i) for i in issue_objs]
return issues

@ram.cache(_render_cachekey)
def reviews(self, volume, issue=None):
if volume not in self.parent.objectIds():
return []
if issue is None:
review_objs = self.parent[volume].getFolderContents(
{"portal_type": ["Review Monograph", "Review Journal"]},
full_objects=True,
)
else:
if issue not in self.parent[volume].objectIds():
return []
review_objs = self.parent[volume][issue].getFolderContents(
{"portal_type": ["Review Monograph", "Review Journal"]},
full_objects=True,
)
review_objs = sorted(review_objs, key=lambda v: listAuthorsAndEditors(v)())
reviews = [self._make_dict(rev) for rev in review_objs]
return reviews

def _formatsize(self, size):
size_kb = size / 1024
display_size_kb = f"{size_kb:n} kB" if size_kb > 0 else ""
if display_size_kb:
display_size_bytes = f" ({size:n} bytes)"
else:
display_size_bytes = f"{size:n} bytes"
display_size = f"{display_size_kb}{display_size_bytes}"
return display_size

0 comments on commit beb9e22

Please sign in to comment.