Update markup of templates to Bootstrap 5 (#173)

* Update markup of all buttons, forms and input elements to Bootstrap 4

* Add documentByLine in the card-header. Add commentBody in the card-body

* Update CHANGES.txt

* Update @@manage-comments.pt moderation interface with Bootstrap 4

* bs5 form updates

* add bootstrap icon from resolver

* update bindings for button

* update markup for bootstrap 5

* turn configlet portlets into menu

* turn configlet portlets into menu (2)

* bootstrap b1 changes

* major version bump

Co-authored-by: Peter Holzer <peter.holzer@agitator.com>
Co-authored-by: Jens W. Klein <jk@kleinundpartner.at>
Co-authored-by: Peter Mathis <peter.mathis@kombinat.at>
This commit is contained in:
André Gonçalves 2021-02-13 09:56:21 +01:00 committed by GitHub
parent e5568c32af
commit 5d0d97a432
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 217 additions and 187 deletions

View File

@ -8,6 +8,16 @@ Changelog
.. towncrier release notes start
3.4.4 (2020-10-09)
------------------
New features:
- Update templates markup to Bootstrap 4.
[andreesg]
3.4.3 (2020-09-28)
------------------

View File

@ -17,16 +17,17 @@
<div class="reply"
tal:condition="python:isAnon and not isAnonymousDiscussionAllowed">
<form tal:attributes="action view/login_action">
<input class="standalone loginbutton"
<button class="standalone loginbutton mb-3"
type="submit"
value="Log in to add comments"
i18n:attributes="value label_login_to_add_comments;"
/>
i18n:translate="label_login_to_add_comments"
>Log in to add comments</button>
</form>
</div>
<div class="discussion"
tal:attributes="class python: showCommenterImage and 'discussion showCommenterImage' or 'discussion';"
tal:attributes="class python: showCommenterImage and 'discussion showCommenterImage card' or 'discussion card';"
tal:condition="has_replies">
<tal:getreplies repeat="reply_dict replies">
@ -46,131 +47,138 @@
id comment_id"
tal:condition="python:canReview or review_state == 'published'">
<div class="commentImage" tal:condition="showCommenterImage">
<a href="" tal:condition="has_author_link"
tal:attributes="href author_home_url">
<img src="defaultUser.png"
alt=""
class="defaultuserimg"
height="32"
tal:attributes="src portrait_url;
alt reply/author_name" />
</a>
<img src="defaultUser.png"
alt=""
class="defaultuserimg"
height="32"
tal:condition="not: has_author_link"
tal:attributes="src portrait_url;
alt reply/author_name" />
<div class="card-header">
<div class="commentImage" tal:condition="showCommenterImage">
<a href="" tal:condition="has_author_link"
tal:attributes="href author_home_url">
<img src="defaultUser.png"
alt=""
class="defaultuserimg"
height="32"
tal:attributes="src portrait_url;
alt reply/author_name" />
</a>
<img src="defaultUser.png"
alt=""
class="defaultuserimg"
height="32"
tal:condition="not: has_author_link"
tal:attributes="src portrait_url;
alt reply/author_name" />
</div>
<div class="documentByLine">
<tal:name>
<a href=""
tal:condition="has_author_link"
tal:content="reply/author_name"
tal:attributes="href author_home_url">
Poster Name
</a>
<span tal:condition="not: has_author_link"
tal:replace="reply/author_name" />
<span tal:condition="not: reply/author_name"
i18n:translate="label_anonymous">Anonymous</span>
</tal:name>
<tal:posted i18n:translate="label_says">says:</tal:posted>
<div class="commentDate"
tal:content="python:view.format_time(reply.modification_date)">
8/23/2001 12:40:44 PM
</div>
</div>
</div>
<div class="card-body">
<div class="commentBody">
<div class="documentByLine">
<tal:name>
<a href=""
tal:condition="has_author_link"
tal:content="reply/author_name"
tal:attributes="href author_home_url">
Poster Name
</a>
<span tal:condition="not: has_author_link"
tal:replace="reply/author_name" />
<span tal:condition="not: reply/author_name"
i18n:translate="label_anonymous">Anonymous</span>
</tal:name>
<tal:posted i18n:translate="label_says">says:</tal:posted>
<div class="commentDate"
tal:content="python:view.format_time(reply.modification_date)">
8/23/2001 12:40:44 PM
</div>
</div>
<span tal:replace="structure reply/getText" />
<div class="commentBody">
<div class="commentActions row row-cols-lg-auto g-3 align-items-center">
<form name="delete"
action=""
method="post"
class="commentactionsform"
tal:condition="python:not canDelete and isDeleteOwnCommentAllowed and view.could_delete_own(reply)"
tal:attributes="action string:${reply/absolute_url}/@@delete-own-comment;
style python:view.can_delete_own(reply) and 'display: inline' or 'display: none';
id string:delete-${comment_id}">
<button name="form.button.DeleteComment"
class="destructive btn btn-danger"
type="submit"
value="Delete"
i18n:attributes="value label_delete;"
i18n:translate="label_delete"
>Delete</button>
</form>
<form name="delete"
action=""
method="post"
class="commentactionsform"
tal:condition="python:canDelete"
tal:attributes="action string:${reply/absolute_url}/@@moderate-delete-comment;
id string:delete-${comment_id}">
<button name="form.button.DeleteComment"
class="destructive btn btn-danger"
type="submit"
value="Delete"
i18n:attributes="value label_delete;"
i18n:translate="label_delete"
>Delete</button>
</form>
<span tal:replace="structure reply/getText" />
<tal:edit tal:condition="python:isEditCommentAllowed and canEdit">
<!-- plone 5 will have auth_token available
so we'll use modal pattern -->
<a class="pat-plone-modal context commentactionsform btn btn-primary"
tal:condition="auth_token"
tal:attributes="href string:${reply/absolute_url}/@@edit-comment?_authenticator=${auth_token}"
i18n:translate="Edit">Edit</a>
<form name="edit"
action=""
method="get"
class="commentactionsform"
tal:condition="not: auth_token"
tal:attributes="action string:${reply/absolute_url}/@@edit-comment;
id string:edit-${comment_id}">
<button name="form.button.EditComment"
class="context btn btn-primary"
type="submit"
value="Edit"
i18n:attributes="value label_edit;"
i18n:translate="label_edit"
>Edit</button>
</form>
</tal:edit>
<div class="commentActions">
<form name="delete"
action=""
method="post"
class="commentactionsform"
tal:condition="python:not canDelete and isDeleteOwnCommentAllowed and view.could_delete_own(reply)"
tal:attributes="action string:${reply/absolute_url}/@@delete-own-comment;
style python:view.can_delete_own(reply) and 'display: inline' or 'display: none';
id string:delete-${comment_id}">
<input name="form.button.DeleteComment"
class="destructive"
type="submit"
value="Delete"
i18n:attributes="value label_delete;"
/>
</form>
<form name="delete"
action=""
method="post"
class="commentactionsform"
tal:condition="python:canDelete"
tal:attributes="action string:${reply/absolute_url}/@@moderate-delete-comment;
id string:delete-${comment_id}">
<input name="form.button.DeleteComment"
class="destructive"
type="submit"
value="Delete"
i18n:attributes="value label_delete;"
/>
</form>
<tal:edit tal:condition="python:isEditCommentAllowed and canEdit">
<!-- plone 5 will have auth_token available
so we'll use modal pattern -->
<a class="pat-plone-modal context commentactionsform"
tal:condition="auth_token"
tal:attributes="href string:${reply/absolute_url}/@@edit-comment?_authenticator=${auth_token}"
i18n:translate="Edit">Edit</a>
<form name="edit"
<!-- Workflow actions (e.g. 'publish') -->
<form name=""
action=""
method="get"
class="commentactionsform"
tal:condition="not: auth_token"
tal:attributes="action string:${reply/absolute_url}/@@edit-comment;
id string:edit-${comment_id}">
<input name="form.button.EditComment"
class="context"
tal:condition="canReview"
tal:repeat="action reply_dict/actions|nothing"
tal:attributes="action string:${reply/absolute_url}/@@transmit-comment;
name action/id;
id string:${action/id}-${comment_id}">
<input type="hidden" name="workflow_action" tal:attributes="value action/id" />
<button name="form.button.TransmitComment"
class="context btn btn-primary"
type="submit"
value="Edit"
i18n:attributes="value label_edit;"
/>
tal:attributes="value action/title"
tal:content="action/title"
i18n:attributes="value"
></button>
</form>
</tal:edit>
<!-- Workflow actions (e.g. 'publish') -->
<form name=""
action=""
method="get"
class="commentactionsform"
tal:condition="canReview"
tal:repeat="action reply_dict/actions|nothing"
tal:attributes="action string:${reply/absolute_url}/@@transmit-comment;
name action/id;
id string:${action/id}-${comment_id}">
<input type="hidden" name="workflow_action" tal:attributes="value action/id" />
<input name="form.button.TransmitComment"
class="context"
type="submit"
tal:attributes="value action/title"
i18n:attributes="value"
/>
</form>
</div>
</div>
</div>
<button class="context reply-to-comment-button hide allowMultiSubmit btn btn-primary"
tal:condition="python:isDiscussionAllowed and (isAnon and isAnonymousDiscussionAllowed or userHasReplyPermission)"
i18n:translate="label_reply">
Reply
</button>
</div>
<button class="context reply-to-comment-button hide allowMultiSubmit"
tal:condition="python:isDiscussionAllowed and (isAnon and isAnonymousDiscussionAllowed or userHasReplyPermission)"
i18n:translate="label_reply">
Reply
</button>
</div>
</tal:getreplies>
@ -185,12 +193,13 @@
<div class="reply"
tal:condition="python:has_replies and (isAnon and not isAnonymousDiscussionAllowed)">
<form tal:attributes="action view/login_action">
<input class="standalone loginbutton"
<form tal:attributes="action view/login_action" class="mb-3">
<button class="standalone loginbutton btn btn-primary"
type="submit"
value="Log in to add comments"
i18n:attributes="value label_login_to_add_comments;"
/>
i18n:translate="label_login_to_add_comments"
>Log in to add comments</button>
</form>
</div>

View File

@ -140,9 +140,9 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
def updateActions(self):
super(CommentForm, self).updateActions()
self.actions['cancel'].addClass('standalone')
self.actions['cancel'].addClass('btn btn-secondary')
self.actions['cancel'].addClass('hide')
self.actions['comment'].addClass('context')
self.actions['comment'].addClass('btn btn-primary')
def get_author(self, data):
context = aq_inner(self.context)

View File

@ -8,7 +8,7 @@
<body>
<article id="content"
tal:attributes="class view/settings"
metal:fill-slot="prefs_configlet_content">
metal:fill-slot="prefs_configlet_main">
<div class="portalMessage warning"
role="status"
@ -55,12 +55,6 @@
Portal status message
</div>
<a id="setup-link" class="link-parent"
tal:attributes="href string:${view/site_url}/@@overview-controlpanel"
i18n:translate="">
Site Setup
</a>
<h1 class="documentFirstHeading" tal:content="view/label">View Title</h1>
<div id="content-core">

View File

@ -22,7 +22,7 @@ require(["jquery", "pat-registry"], function($, registry) {
/**********************************************************************
* Delete a single comment.
**********************************************************************/
$("input[name='form.button.moderation.DeleteComment']").click(function(e) {
$("button[name='form.button.moderation.DeleteComment']").click(function(e) {
e.preventDefault();
var row = $(this).closest("tr");
var path = row.find("[name='selected_obj_paths:list']").attr("value");
@ -52,7 +52,7 @@ require(["jquery", "pat-registry"], function($, registry) {
/**********************************************************************
* Transmit a single comment.
**********************************************************************/
$('input[name="form.button.moderation.TransmitComment"]').click(function(
$('button[name="form.button.moderation.TransmitComment"]').click(function(
e
) {
e.preventDefault();
@ -104,7 +104,7 @@ require(["jquery", "pat-registry"], function($, registry) {
/**********************************************************************
* Bulk actions for comments (delete, publish)
**********************************************************************/
$("input[name='form.button.BulkAction']").click(function(e) {
$("button[name='form.button.BulkAction']").click(function(e) {
e.preventDefault();
var form = $(this).closest("form");
var target = $(form).attr("action");

View File

@ -51,7 +51,7 @@
</span>
</div>
<form
<form class="mb-3"
method="post"
action="#"
tal:condition="moderation_enabled"
@ -60,54 +60,68 @@
<fieldset id="fieldset-moderate-comments" class="formPanel">
<div metal:use-macro="here/batch_macros/macros/navigation" />
<table id="review-comments" class="listing">
<div id="review-comments">
<div class="row row-cols-lg-auto g-3 align-items-center mb-2 mt-2" id="bulkactions">
<tal:bulk condition="items">
<div class="col-auto">
<select class="form-select" name="form.select.BulkAction">
<option selected="selected" value="-1" i18n:translate="title_bulkactions">Bulk Actions</option>
<tal:comment tal:replace="nothing"></tal:comment>
<option value="publish"
i18n:translate="bulkactions_publish"
tal:condition="python: filter != 'published'">Approve</option>
<option value="mark_as_spam"
tal:condition="python: filter != 'spam'">Spam</option>
<option value="delete" i18n:translate="bulkactions_delete">Delete</option>
</select>
</div>
<div class="col-auto">
<input type="hidden" name="filter" tal:attributes="value filter" />
<button class="standalone allowMultiSubmit btn btn-primary"
id="dobulkaction"
type="submit"
value="Apply"
name="form.button.BulkAction"
i18n:attributes="value label_apply;"
i18n:translate="label_apply">Apply</button>
</div>
</tal:bulk>
<div class="flex-grow-1">
<div class="row row-cols-lg-auto g-3 align-items-center justify-content-end" tal:condition="view/moderation_multiple_state_enabled">
<label i18n:translate="filter_by_state">Filter by state:</label>
<div>
<input class="form-check-input" type="radio" id="all" name="review_state" value="all"
tal:attributes="checked python:request.review_state=='all'" />
<label class="form-check-label" for="all" i18n:translate="">all</label>
</div>
<tal:states tal:repeat="review_state python:['pending', 'published', 'rejected', 'spam']">
<div>
<input class="form-check-input" type="radio" name="review_state"
tal:attributes="
value review_state;
id review_state;
checked python:request.review_state==review_state" />
<label class="form-check-label"
tal:attributes="for review_state"><span tal:content="python:translationhelper.translate_comment_review_state(review_state)">review_state</span></label>
</div>
</tal:states>
</div>
</div>
</div>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th colspan="7">
<fieldset tal:condition="view/moderation_multiple_state_enabled">
<input type="radio" id="all" name="review_state" value="all"
tal:attributes="checked python:request.review_state=='all'" />
<label for="all" i18n:translate="">all</label>
<tal:workflow-filter tal:repeat="review_state python:['pending', 'published', 'rejected', 'spam']">
<input type="radio" name="review_state"
tal:attributes="
value review_state;
id review_state;
checked python:request.review_state==review_state" />
<label tal:attributes="for review_state"><span tal:content="python:translationhelper.translate_comment_review_state(review_state)">review_state</span></label>
</tal:workflow-filter>
</fieldset>
</th>
</tr>
<tr tal:condition="items">
<th id="bulkactions" class="nosort" colspan="7">
<select name="form.select.BulkAction">
<option selected="selected" value="-1" i18n:translate="title_bulkactions">Bulk Actions</option>
<tal:comment tal:replace="nothing"></tal:comment>
<option value="publish"
i18n:translate="bulkactions_publish"
tal:condition="python: filter != 'published'">Approve</option>
<option value="mark_as_spam"
tal:condition="python: filter != 'spam'">Spam</option>
<option value="delete" i18n:translate="bulkactions_delete">Delete</option>
</select>
<input type="hidden" name="filter" tal:attributes="value filter" />
<input id="dobulkaction"
type="submit"
class="standalone allowMultiSubmit"
value="Apply"
name="form.button.BulkAction"
i18n:attributes="value label_apply;" />
</th>
</tr>
<tr tal:condition="items">
<th class="nosort"><input name="check_all" type="checkbox" value="0" /></th>
<th class="nosort" i18n:translate="heading_commenter">Commenter</th>
<th class="nosort" i18n:translate="heading_date">Date</th>
<th class="nosort" i18n:translate="heading_in_reponse_to">In Response To</th>
<th class="nosort" i18n:translate="heading_comment">Comment</th>
<th class="nosort" i18n:translate="heading_changedby">Last Action</th>
</tr>
<tr tal:condition="items">
<th scope="col" class="nosort"><input name="check_all" type="checkbox" value="0" /></th>
<th scope="col" class="nosort" i18n:translate="heading_commenter">Commenter</th>
<th scope="col" class="nosort" i18n:translate="heading_date">Date</th>
<th scope="col" class="nosort" i18n:translate="heading_in_reponse_to">In Response To</th>
<th scope="col" class="nosort" i18n:translate="heading_comment">Comment</th>
<th scope="col" class="nosort" i18n:translate="heading_changedby">Last Action</th>
</tr>
</thead>
<tbody>
<tal:block repeat="item batch"
@ -146,7 +160,7 @@
tal:content="item/in_response_to" />
</td>
<td tal:attributes="class python:colorclass(item.review_state)">
<div>
<div class="mb-2">
<span tal:replace="item/Description"/>
<a href=""
tal:attributes="href string:$item_url/getText"
@ -162,33 +176,35 @@
tal:attributes="value item/getURL"
/>
<!-- delete -->
<input id=""
class="destructive comment-delete-button"
<button id=""
class="destructive comment-delete-button btn btn-sm btn-danger"
type="submit"
value="Delete"
name="form.button.moderation.DeleteComment"
i18n:attributes="value label_delete;"
tal:attributes="id item/id"
/>
i18n:translate="label_delete"
>Delete</button>
<!-- edit -->
<a class="pat-plone-modal context" href="#"
<a class="pat-plone-modal context btn btn-sm btn-primary" href="#"
tal:attributes="href python:item_url+'/@@edit-comment?review_state=' + item.review_state">Edit</a>
<!-- workflow actions -->
<tal:transitions
tal:define="
transitions python:view.allowed_transitions(item_obj)">
<input name="form.button.moderation.TransmitComment"
<button name="form.button.moderation.TransmitComment"
tal:repeat="transition transitions"
class="context"
class="context btn btn-sm btn-primary"
type="submit"
value="Label"
tal:content="python:translationhelper.translate(transition['title'])"
tal:attributes="id string:${item/id}_${transition/id};
data-transition transition/id;
value python:translationhelper.translate(transition['title']);
style python:transition['id']=='publish' and 'background-color: #5cb85c;; border-color: #4cae4c;;' or '';
"
/>
>Label</button>
</tal:transitions>
</div>
</td>
@ -202,6 +218,7 @@
</tal:block>
</tbody>
</table>
</div>
<div metal:use-macro="here/batch_macros/macros/navigation" />
</fieldset>
</form>

View File

@ -11,7 +11,7 @@
appId="plone.app.discussion"
category="plone-general"
condition_expr=""
icon_expr="string:${portal_url}/discussionitem_icon.png"
icon_expr="string:chat-square-dots"
url_expr="string:${portal_url}/@@discussion-controlpanel"
visible="True"
i18n:attributes="title">

View File

@ -4,7 +4,7 @@ from setuptools import find_packages
from setuptools import setup
version = '3.4.4.dev0'
version = '4.0.0.dev0'
install_requires = [
'setuptools',