-
Notifications
You must be signed in to change notification settings - Fork 34
docs: Update docs to explain the djangocms_versioning contract #511
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
Merged
Merged
Changes from 4 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
60a25e6
docs: Update docs to explain the djangocms_versioning contract
fsbraun 8bd03d1
Merge branch 'master' into docs/explain-contract
fsbraun cea77ef
Update docs/introduction/working_with_pages.rst
fsbraun 805547b
Update docs/introduction/working_with_pages.rst
fsbraun aeb6a23
Update docs/explanations/admin_options.rst
fsbraun File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,181 @@ | ||
| .. _versioning_contract: | ||
|
|
||
| Versioning contract | ||
| =================== | ||
|
|
||
| Django CMS uses a contract-based approach for versioning, allowing different versioning | ||
| implementations to integrate with the CMS and its ecosystem. **djangocms-versioning defines | ||
| the versioning contract** for django CMS. This section describes the contract that | ||
| djangocms-versioning does implement and other versioning packages must implement to work | ||
| with django CMS. | ||
|
|
||
| Overview | ||
| -------- | ||
|
|
||
| The contract is implemented through django CMS's ``CMSAppExtension`` mechanism in the | ||
| ``cms_config.py`` module. When installed, djangocms-versioning becomes the versioning | ||
| provider for all content types that register with it—including django CMS pages, | ||
| aliases, stories, and any custom content models. | ||
|
|
||
| .. note:: | ||
|
|
||
| **djangocms-versioning** is the reference implementation endorsed by the django CMS | ||
| Association. | ||
|
|
||
| Contract definition | ||
| ------------------- | ||
|
|
||
| The contract is defined in djangocms-versioning's ``cms_config.py`` using the | ||
| ``contract`` class attribute, a 2-tuple consisting of the contract name (``"djangocms_versioning"``) | ||
| and the contract class (``VersionableItem``): | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| from cms.app_base import CMSAppExtension | ||
| from .datastructures import VersionableItem | ||
|
|
||
| class VersioningCMSExtension(CMSAppExtension): | ||
| contract = "djangocms_versioning", VersionableItem | ||
|
|
||
| def __init__(self): | ||
| self.versionables = [] | ||
|
|
||
| def configure_app(self, cms_config): | ||
| # Process the versioning configuration | ||
| if hasattr(cms_config, "versioning"): | ||
| self.handle_versioning_setting(cms_config) | ||
| # ... additional setup | ||
|
|
||
| The ``contract`` attribute is a tuple of: | ||
|
|
||
| 1. The contract name (``"djangocms_versioning"``) | ||
| 2. The ``VersionableItem`` class that apps use to register their content models | ||
|
|
||
| This allows other packages to register for versioning without importing directly from | ||
| djangocms-versioning, enabling alternative implementations to provide the same contract. | ||
|
|
||
| Contract components | ||
| ------------------- | ||
|
|
||
| VersionableItem class | ||
| ~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| The ``VersionableItem`` class defines how a content model participates in versioning. | ||
| At minimum, it must accept: | ||
|
|
||
| ``content_model`` | ||
| The Django model class that stores versioned content (the :term:`content model`). | ||
|
|
||
| ``grouper_field_name`` | ||
| The name of the foreign key field on the content model that points to the | ||
| :term:`grouper model`. | ||
|
|
||
| ``copy_function`` | ||
| An (optional) callable that creates a copy of a content object when creating new versions. | ||
|
|
||
| Additional optional parameters are djangocms-versioning-specific and may include: | ||
|
|
||
| - ``extra_grouping_fields``: Additional fields for grouping versions (e.g., ``language``) | ||
| - ``on_publish``, ``on_unpublish``, ``on_draft_create``, ``on_archive``: Lifecycle hooks | ||
| - ``preview_url``: Function to generate preview URLs for versions | ||
| - ``content_admin_mixin``: Custom admin mixin for the content model | ||
| - ``grouper_admin_mixin``: Custom admin mixin for the grouper model | ||
|
|
||
| Manager modifications | ||
| ~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| A versioning package typically modifies the content model's managers: | ||
|
|
||
| ``objects`` manager | ||
| Should filter to return only published content by default, ensuring unpublished | ||
| content never leaks to the public. | ||
|
|
||
| ``admin_manager`` | ||
| Should provide access to all content versions, for use in admin contexts only. | ||
|
|
||
| These managers enable the pattern: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| # Public queries - only published content | ||
| PostContent.objects.filter(...) | ||
|
|
||
| # Admin queries - all versions accessible | ||
| PostContent.admin_manager.filter(...) | ||
|
|
||
| Registration mechanism | ||
| ---------------------- | ||
|
|
||
| Content models register for versioning via ``cms_config.py``: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| # myapp/cms_config.py | ||
| from cms.app_base import CMSAppConfig | ||
|
|
||
| from .models import MyContent | ||
|
|
||
|
|
||
| class MyAppConfig(CMSAppConfig): | ||
| djangocms_versioning_enabled = True # <contract>_enabled = True | ||
|
|
||
| def __init__(self, app): | ||
| super().__init__(app) | ||
|
|
||
| # Dynamically get the installed contract object | ||
| VersionableItem = self.get_contract("djangocms_versioning") | ||
|
|
||
| self.versioning = [ | ||
| VersionableItem( | ||
| content_model=MyContent, | ||
| grouper_field_name="grouper", | ||
| grouper_admin_mixin="__default__", | ||
| ), | ||
| ] | ||
|
|
||
| The ``djangocms_versioning_enabled = True`` attribute signals that this app wants to | ||
| use the versioning extension. The ``get_contract("djangocms_versioning")`` call retrieves the | ||
| ``VersionableItem`` class from the installed versioning package, allowing the app to | ||
| register its content models for versioning. | ||
|
|
||
| Implementing alternative versioning packages | ||
| -------------------------------------------- | ||
|
|
||
| Alternative versioning packages must follow the contract defined by djangocms-versioning. | ||
| Specifically, they must: | ||
|
|
||
| 1. **Export a VersionableItem class** (or compatible equivalent) that other packages | ||
| can discover and use for registration. | ||
|
|
||
| 2. **Process the** ``versioning`` **attribute** from ``CMSAppConfig`` subclasses that | ||
| have ``djangocms_versioning_enabled = True``. | ||
|
|
||
| 3. **Modify content model managers** to provide the ``objects`` / ``admin_manager`` | ||
| pattern expected by django CMS and ecosystem packages. | ||
|
|
||
| 4. **(Optional) Provide version state information** for the CMS toolbar and admin | ||
| interfaces. djangocms-versioning does this by injecting a ``content_indicator`` | ||
| method onto content models that returns status strings (e.g., ``"published"``, | ||
| ``"draft"``, ``"dirty"``). Alternative implementations may define their own states | ||
| or omit this functionality. | ||
|
|
||
| Ecosystem compatibility | ||
| ----------------------- | ||
|
|
||
| Packages in the django CMS ecosystem (such as djangocms-alias and djangocms-stories) | ||
| register their content models using the versioning contract. When you install a | ||
| versioning package, it becomes responsible for managing versions of *all* registered | ||
| content types. | ||
|
|
||
| This means: | ||
|
|
||
| - Switching versioning packages affects all versioned content across your site | ||
| - Alternative implementations must handle registrations from ecosystem packages | ||
| - The version states and workflow defined by your versioning package apply universally | ||
|
|
||
| See also | ||
| -------- | ||
|
|
||
| - :doc:`/introduction/versioning_integration` for integrating your models with versioning | ||
| - :doc:`advanced_configuration` for customizing versioning behavior | ||
| - :doc:`models` for the Version model reference |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.