mezzanine
mezzanine copied to clipboard
Add feature to allow users editing their owns comments
{% editable comment.comment %} only allows staff to edit comments, please allow also users to edit their own comments.
References:
mezzanine/js/editable.js
mezzanine/core/includes/editable_form.html
- Use editable_form.html as template for editable_user_form.html pointing to {% url "user_edit" %}
mezzanine.core.views.edit
- Create user_edit view by replacing
if not (is_editable(obj, request) and has_site_permission(request.user)):withif request.user != obj.user
I purposely didn't add a pull request, because I don't know how to integrate this with TinyMCE.
I didn't have to bother with TinyMCE. This worked for me:
- Add
mezzanine.core.templatetags.mezzanine_tags.user_editable:
- Here I only changed
is_editable()tois_user_editable()
def user_editable(parsed, context, token):
"""
Add the required HTML to the parsed content for in-line editing,
such as the icon and edit form if the object is deemed to be
editable - either it has an ``editable`` method which returns
``True``, or the logged in user has change permissions for the
model.
"""
def parse_field(field):
field = field.split(".")
obj = context.get(field.pop(0), None)
attr = field.pop()
while field:
obj = getattr(obj, field.pop(0))
if callable(obj):
# Allows {% editable page.get_content_model.content %}
obj = obj()
return obj, attr
fields = [parse_field(f) for f in token.split_contents()[1:]]
if fields:
fields = [f for f in fields if len(f) == 2 and f[0] is fields[0][0]]
if not parsed.strip():
try:
parsed = "".join([str(getattr(*field)) for field in fields])
except AttributeError:
pass
if settings.INLINE_EDITING_ENABLED and fields and "request" in context:
obj = fields[0][0]
if isinstance(obj, Model) and is_user_editable(obj, context["request"]):
field_names = ",".join([f[1] for f in fields])
context["editable_form"] = get_edit_form(obj, field_names)
context["original"] = parsed
t = get_template("includes/editable_form.html")
return t.render(context.flatten())
return parsed
- Add
mezzanine.utils.views.is_user_editable
- Here we only check for
if request.user == obj.userand removed the permission and has_site_permission checks.
def is_user_editable(obj, request):
"""
Returns ``True`` if the object is editable for the request. First
check for a custom ``editable`` handler on the object, otherwise
use the logged in user and check change permissions for the
object's model.
"""
if hasattr(obj, "is_editable"):
return obj.is_editable(request)
else:
return (request.user == obj.user)
- Then we can use
{% user_editable comment.comment %}instead of{% editable comment.comment %}in the templates
Is it okay to add it like this?
We should add this ability for users to edit their own comments. The approach you've taken isn't correct though - inline editing is definitely only intended for administrators.
The correct approach will need to modify the comments_for template tag, which currently adds 2 forms to the template - a reply form, and a new comment form. We could potentially use one of these, or add a third, that gets used to edit a comment, by adding the comment ID to the form. Some handling would also be needed server-side to ensure the user is the owner of the comment being edited.