Skip to content

Feature/plone52 fixes #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ New features:

Bug fixes:

- *add item here*
- Do not filter automatically default pages.
[pgrunewald]


1.2.0 (2020-01-27)
Expand Down
72 changes: 72 additions & 0 deletions plone/formwidget/contenttree/i18n.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/bin/sh
#
# Shell script to manage .po files.
#
# Run this file in the folder main __init__.py of product
#
# E.g. if your product is yourproduct.name
# you run this file in yourproduct.name/yourproduct/name
#
#
# Copyright 2010 mFabrik http://mfabrik.com
#
# http://plone.org/documentation/manual/plone-community-developer-documentation/i18n/localization
#

# Assume the product name is the current folder name
CURRENT_PATH=`pwd`
CATALOGNAME="plone.formwidget.contenttree"

# List of languages
LANGUAGES="de"

# Create locales folder structure for languages
install -d locales
for lang in $LANGUAGES; do
install -d locales/$lang/LC_MESSAGES
done

I18NDUDE=~/Plone/zinstance/bin/i18ndude

if test ! -e $I18NDUDE; then
I18NDUDE=../../../../../bin/i18ndude
fi

if test ! -e $I18NDUDE; then
echo "You must install i18ndude with buildout"
echo "See https://github.com/collective/collective.developermanual/blob/master/source/i18n/localization.txt"
exit
fi

#
# Do we need to merge manual PO entries from a file called manual.pot.
# this option is later passed to i18ndude
#
if test -e locales/manual.pot; then
echo "Manual PO entries detected"
MERGE="--merge locales/manual.pot"
else
echo "No manual PO entries detected"
MERGE=""
fi

# Rebuild .pot
$I18NDUDE rebuild-pot --pot locales/$CATALOGNAME.pot $MERGE --create $CATALOGNAME .


# Compile po files
for lang in $(find locales -mindepth 1 -maxdepth 1 -type d); do

if test -d $lang/LC_MESSAGES; then

PO=$lang/LC_MESSAGES/${CATALOGNAME}.po

# Create po file if not exists
touch $PO

# Sync po file
echo "Syncing $PO"
$I18NDUDE sync --pot locales/$CATALOGNAME.pot $PO
fi
done
#!/bin/sh
2 changes: 0 additions & 2 deletions plone/formwidget/contenttree/input_recurse.pt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
children node/children;
item_url node/getURL;
item_token python:view.getTermByBrain(node['item']).token;
item_icon node/item_icon;
selectable node/selectable;
li_folder_class python:show_children and ' navTreeFolderish' or '';
li_selectable_class python:selectable and ' selectable' or '';
Expand All @@ -16,7 +15,6 @@
<a tal:attributes="href item_token; rel level;
title node/Description;
class string:$item_class">
<img tal:replace="structure item_icon/html_tag|item_icon" />
<span tal:content="node/Title">Selected Item Title</span>
</a>
</tal:block>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2023-06-12 21:11+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0\n"
"Language-Code: en\n"
"Language-Name: English\n"
"Preferred-Encodings: utf-8 latin1\n"
"Domain: DOMAIN\n"

#. Default: "Browse"
#: ./widget.py:274
msgid "label_contenttree_browse"
msgstr "Durchsuchen"
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#--- PLEASE EDIT THE LINES BELOW CORRECTLY ---
#SOME DESCRIPTIVE TITLE.
#FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2023-06-12 21:11+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0\n"
"Language-Code: en\n"
"Language-Name: English\n"
"Preferred-Encodings: utf-8 latin1\n"
"Domain: plone.formwidget.contenttree\n"

#. Default: "Browse"
#: ./widget.py:274
msgid "label_contenttree_browse"
msgstr ""
99 changes: 77 additions & 22 deletions plone/formwidget/contenttree/navtree.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
from zope.interface import implementer, Interface
from Acquisition import aq_inner
from plone.app.layout.navigation.interfaces import INavigationQueryBuilder
from plone.app.layout.navigation.interfaces import INavtreeStrategy
from plone.app.layout.navigation.root import getNavigationRoot
from plone.formwidget.contenttree.interfaces import IContentSource
from plone.formwidget.contenttree.interfaces import IContentTreeWidget
from plone.i18n.normalizer.interfaces import IIDNormalizer
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone import utils
from zope.component import adapts
from zope.component import queryUtility
from zope.interface import Interface
from zope.interface import implementer

from Products.CMFCore.utils import getToolByName

try:
from Products.CMFPlone.browser.navtree import SitemapNavtreeStrategy
SitemapNavtreeStrategy # pyflakes
except ImportError:
# Plone trunk
from plone.app.layout.navigation.sitemap import SitemapNavtreeStrategy
from Products.CMFPlone import utils

from plone.app.layout.navigation.interfaces import INavtreeStrategy
from plone.app.layout.navigation.interfaces import INavigationQueryBuilder

from plone.app.layout.navigation.root import getNavigationRoot

from plone.formwidget.contenttree.interfaces import IContentSource
from plone.formwidget.contenttree.interfaces import IContentTreeWidget


@implementer(INavigationQueryBuilder)
Expand Down Expand Up @@ -110,22 +111,76 @@ def nodeFilter(self, node):
return self.widget.bound_source.isBrainSelectable(node['item'])

def decoratorFactory(self, node):
new_node = super(NavtreeStrategy, self).decoratorFactory(node)

"""Cleanup this method's original
- remove unused plone view, then request is not needed anymore
"""
context = aq_inner(self.context)
# Patch: request empty because acquisiton gone already, but we do not need it anyway
# request = context.REQUEST

newNode = node.copy()
item = node['item']

portalType = getattr(item, 'portal_type', None)
itemUrl = item.getURL()
if portalType is not None and portalType in self.viewActionTypes:
itemUrl += '/view'

useRemoteUrl = False
getRemoteUrl = getattr(item, 'getRemoteUrl', None)
isCreator = self.memberId == getattr(item, 'Creator', None)
if getRemoteUrl and not isCreator:
useRemoteUrl = True

isFolderish = getattr(item, 'is_folderish', None)
showChildren = False
if isFolderish and \
(portalType is None or portalType not in self.parentTypesNQ):
showChildren = True

isFolderish = getattr(item, 'is_folderish', None)

# Patch: remove unused view
#layout_view = getMultiAdapter((context, request), name=u'plone_layout')

newNode['Title'] = utils.pretty_title_or_id(context, item)
newNode['id'] = item.getId
newNode['UID'] = item.UID
newNode['absolute_url'] = itemUrl
newNode['getURL'] = itemUrl
newNode['path'] = item.getPath()
newNode['Creator'] = getattr(item, 'Creator', None)
newNode['creation_date'] = getattr(item, 'CreationDate', None)
newNode['portal_type'] = portalType
newNode['review_state'] = getattr(item, 'review_state', None)
newNode['Description'] = getattr(item, 'Description', None)
newNode['show_children'] = showChildren
# Allow entering children even if the type would not normally be
# expanded in the navigation tree
new_node['show_children'] = getattr(new_node['item'],
'is_folderish',
False)

newNode['show_children'] = getattr(item,
'is_folderish',
False)
newNode['no_display'] = False # We sort this out with the nodeFilter
# BBB getRemoteUrl and link_remote are deprecated, remove in Plone 4
newNode['getRemoteUrl'] = getattr(item, 'getRemoteUrl', None)
newNode['useRemoteUrl'] = useRemoteUrl
newNode['link_remote'] = (
newNode['getRemoteUrl'] and newNode['Creator'] != self.memberId
)
# Mark selectable nodes
new_node['selectable'] = self.widget.bound_source.isBrainSelectable(
new_node['item'])
newNode['selectable'] = self.widget.bound_source.isBrainSelectable(item)

idnormalizer = queryUtility(IIDNormalizer)
newNode['normalized_portal_type'] = idnormalizer.normalize(portalType)
newNode['normalized_review_state'] = idnormalizer.normalize(
newNode['review_state']
)
newNode['normalized_id'] = idnormalizer.normalize(newNode['id'])

# turn all strings to unicode to render non ascii characters
# in the recursion template
for key, value in new_node.items():
for key, value in newNode.items():
if isinstance(value, str):
new_node[key] = unicode(value, self.site_encoding)
newNode[key] = unicode(value, self.site_encoding)

return new_node
return newNode
9 changes: 0 additions & 9 deletions plone/formwidget/contenttree/profiles/default/cssregistry.xml

This file was deleted.

8 changes: 0 additions & 8 deletions plone/formwidget/contenttree/profiles/default/jsregistry.xml

This file was deleted.

2 changes: 1 addition & 1 deletion plone/formwidget/contenttree/profiles/default/metadata.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<metadata>
<version>1.0a6</version>
<version>1.3</version>
<dependencies>
<dependency>profile-plone.formwidget.autocomplete:default</dependency>
</dependencies>
Expand Down
18 changes: 18 additions & 0 deletions plone/formwidget/contenttree/profiles/default/registry.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<registry>
<records prefix="plone.resources/plone.formwidget.contenttree"
interface='Products.CMFPlone.interfaces.IResourceRegistry'>
<value key="js">++resource++plone.formwidget.contenttree/contenttree.js</value>
<value key="css">
<element>++resource++plone.formwidget.contenttree/contenttree.css</element>
</value>
</records>

<records prefix="plone.bundles/plone-legacy"
interface='Products.CMFPlone.interfaces.IBundleRegistry'>
<value key="resources" purge="false">
<element>plone.formwidget.contenttree</element>
</value>
<value key="merge_with"></value>
</records>
</registry>
49 changes: 49 additions & 0 deletions plone/formwidget/contenttree/tests/robot/keywords.robot
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
*** Settings ***

Documentation *WARNING* This resource is not stable yet and keywords may be
... renamed, removed or relocated without notice.

Resource plone/app/robotframework/keywords.robot
Resource plone/app/robotframework/selenium.robot

*** Variables ***


*** Keywords ***
Wait Until ContentTree Finished Loading
Wait Until Page Does Not Contain css=div.contenttreeWidget .wait

Click Add In ContentTree Widget
[Arguments] ${field_id}
Wait Until Element Is Visible css=#${field_id}-widgets-query + input.searchButton
Click Button css=#${field_id}-widgets-query + input.searchButton
Wait Until ContentTree Finished Loading

Open Folderish In ContentTree
[Documentation] Returns the current title, which can be used as parent.
[Arguments] ${title} ${parent}=${EMPTY}
Run Keyword If '${parent}'
... Click Element xpath=//div[contains(@class, 'contenttreeWidget')]//li[.//span[text()='${parent}']]//li//span[text()='${title}']/..
... ELSE Click Element xpath=//div[contains(@class, 'contenttreeWidget')]//li//span[text()='${title}']/..
Wait Until ContentTree Finished Loading
[Return] ${title}

Choose Item With Title In ContentTree
[Arguments] ${title}
Wait Until Page Contains Element xpath=//div[contains(@class, 'contenttreeWidget')]//li//span[text()='${title}']/..
Scroll Element Into View xpath=//div[contains(@class, 'contenttreeWidget')]//li//span[text()='${title}']/..
Click Element xpath=//div[contains(@class, 'contenttreeWidget')]//li//span[text()='${title}']/..


Item With Title Cannot Be Chosen In ContentTree
[Arguments] ${title}
Click Element xpath=//div[contains(@class, 'contenttreeWidget')]//li//span[text()='${title}']/..
${success} = Run Keyword And Return Status Wait until keyword succeeds 10s 1s Page Should Contain Element sizzle=div.contenttreeWidget li.navTreeCurrentItem span:contains(${title})
Should Not Be True ${success} The item with title ${title} should not have been able to chosen.

Confirm Item Selection In ContentTree
Click Element css=input.contentTreeAdd

Get Found Item Count In ContentTree
${value} = Get Element Count css=.contenttreeWidget li
[Return] ${value}
5 changes: 1 addition & 4 deletions plone/formwidget/contenttree/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,6 @@ def __call__(self):
if directory is not None:
navtree_query['path'] = {'depth': 1, 'query': directory}

if 'is_default_page' not in navtree_query:
navtree_query['is_default_page'] = False

content = closest_content(context)

strategy = getMultiAdapter((content, widget), INavtreeStrategy)
Expand Down Expand Up @@ -274,7 +271,7 @@ def js_extra(self):
klass=self.klass,
title=self.title,
button_val=translate(
_(u'label_contenttree_browse', default=u'browse...'),
_(u'label_contenttree_browse', default=u'Browse'),
context=self.request,
),
)
Expand Down