Closed peppelinux closed 3 years ago
Probably we're changing our approach in this way. Entities to be preview are:
Previewable entities will have 3 specialized fields:
draft_of = models.IntegerField(null=True, blank=True)
locked_by = models.ForeignKey(get_user_model(), null=True, blank=True)
locked_time = models.DateTimeField(null=True, blank=True)
Using an editorial board specialized APP, when an Entity is opened for editing using its Change Form, an ajax call (client side js) would be used to send a "ping" every N seconds, N would be configured with a global setting parameter. This call would be handled by a Rest API resource, this updates locked_by
and locked_time
fields. This API resource would also check user authorizations (only editorial board users would have this power ...) and also a special csrftoken for XSS prevention.
A locked entity cannot be edited by others Editorial Board Users, until locked_time have been expired. Other users can see that the content is locked and who is working on that (locked_by).
When an entity has been created as a Draft it will be saved as is and it simply won't be published. When instead it would be modified/changed as a Draft, it will be saved as a copy of the original one, original entity's pk would be filled in draft_of
field. A special suffix will be also added in its name, eg: f'{self.name}-draft-{draft_number}
.
Only Drafts can be previewed. When a Draft is previewed the user have to choose the Context where it would have to be rendered to (website Home or sub path ...). This is quite simple for a Page because it have only one context/webpath. For Publications, Menus and Carousels, instead, user needs to choose the related context to deal with. draft would also be rendered choosing the context/webpath.
A Draft request
simply add a request argument called ?unicms_draft_preview=True
.
A Django middleware intercept this argument and store in the user's session (a cookie storage would be better) that He's working in preview mode. Preview mode makes that all the DRAFT entities, in a requested WebPath/context, would be displayed, if they're present in the database. Preview mode also add a pre-head div in the html templates (with a navigation bar), a specialized template tag would be involved to tell the users that's a PREVIEW MODE. Another UI element will appear, for each previewed entry, if it's a draft it would be marked with this element (related position top-right).
unicms url/content dispatcher, unicms handlers and template blocks have to check if the user sets the preview mode ON in its session. If true:
Results:
If the content is a draft of an existing published one: The user see the page as it would have been a published one, with the overloading of all the DRAFT entries.
If the content is a draft of something that would be contextualized (publication, menu, carousel) The user see the draft content and every draft element that are usually involved in that context. To prevent this a draft would be disabled (is_active=False)
IF the content is a unrelated draft This means that theresn't any published content related to this draft. Dispatcher/blocks/Handlers would query the draft and use this as it is, there will not values to swaps/overloading.
A Page needs needs to be previewed with all the elements related to it:
preview already deployed in cmspages regarding locks: REDIS ttl and nothing more
pages, publications, menus, carousels needs to be previewed. that's the approach for doing this:
cms_previews
and the content_type, eg:/cms_previews/<webpath_pk:id>/<app_label:str>/<model:str>/<pk:int>
see: https://github.com/UniversitaDellaCalabria/Portale-PoC/blob/ad805537dd0e3fa006bb5240925912b241ae0bef/unicms/cms_previews/views.py#L13