<commit_before>.. _placeholders_outside_cms:

#######################################
How to use placeholders outside the CMS
#######################################

Placeholders are special model fields that django CMS uses to render
user-editable content (plugins) in templates. That is, it's the place where a
user can add text, video or any other plugin to a webpage, using the same
frontend editing as the CMS pages.

Placeholders can be viewed as containers for :class:`~cms.models.pluginmodel.CMSPlugin` instances, and
can be used outside the CMS in custom applications using the
:class:`~cms.models.fields.PlaceholderField`.

By defining one (or several) :class:`~cms.models.fields.PlaceholderField` on a
custom model you can take advantage of the full power of :class:`~cms.models.pluginmodel.CMSPlugin`.

***********
Get started
***********

You need to define a :class:`~cms.models.fields.PlaceholderField` on the model you would like to
use::

    from django.db import models
    from cms.models.fields import PlaceholderField

    class MyModel(models.Model):
        # your fields
        my_placeholder = PlaceholderField('placeholder_name')
        # your methods


The :class:`~cms.models.fields.PlaceholderField` has one required parameter, a string ``slotname``.

The ``slotname`` is used in templates, to determine where the placeholder's plugins should appear
in the page, and in the placeholder configuration :setting:`CMS_PLACEHOLDER_CONF`, which determines
which plugins may be inserted into this placeholder.

You can also use a callable for the ``slotname``, as in::

    from django.db import models
    from cms.models.fields import PlaceholderField

    def my_placeholder_slotname(instance):
        return 'placeholder_name'

    class MyModel(models.Model):
        # your fields
        my_placeholder = PlaceholderField(my_placeholder_slotname)
        # your methods

.. warning::

    For security reasons the related_name for a
    :class:`~cms.models.fields.PlaceholderField` may not be suppressed using
    ``'+'``; this allows the cms to check permissions properly. Attempting to do
    so will raise a :exc:`ValueError`.

.. note::

    If you add a PlaceholderField to an existing model, you'll be able to see
    the placeholder in the frontend editor only after saving the relevant instance.

Admin Integration
=================

.. versionchanged:: 3.0

Your model with ``PlaceholderFields`` can still be edited in the admin. However, any
PlaceholderFields in it will **only be available for editing from the frontend**.
``PlaceholderFields`` **must** not be present in any ``fieldsets``, ``fields``, ``form`` or other
``ModelAdmin`` field's definition attribute.

To provide admin support for a model with a ``PlaceholderField`` in your application's admin, you
need to use the mixin :class:`~cms.admin.placeholderadmin.PlaceholderAdminMixin` along with the
:class:`~django.contrib.admin.ModelAdmin`. Note that the ``PlaceholderAdminMixin`` **must** precede
the ``ModelAdmin`` in the class definition::

    from django.contrib import admin
    from cms.admin.placeholderadmin import PlaceholderAdminMixin
    from myapp.models import MyModel

    class MyModelAdmin(PlaceholderAdminMixin, admin.ModelAdmin):<commit_msg>Notice about mixin (#7152)<commit_after>.. _placeholders_outside_cms:

#######################################
How to use placeholders outside the CMS
#######################################

Placeholders are special model fields that django CMS uses to render
user-editable content (plugins) in templates. That is, it's the place where a
user can add text, video or any other plugin to a webpage, using the same
frontend editing as the CMS pages.

Placeholders can be viewed as containers for :class:`~cms.models.pluginmodel.CMSPlugin` instances, and
can be used outside the CMS in custom applications using the
:class:`~cms.models.fields.PlaceholderField`.

By defining one (or several) :class:`~cms.models.fields.PlaceholderField` on a
custom model you can take advantage of the full power of :class:`~cms.models.pluginmodel.CMSPlugin`.

***********
Get started
***********

You need to define a :class:`~cms.models.fields.PlaceholderField` on the model you would like to
use::

    from django.db import models
    from cms.models.fields import PlaceholderField

    class MyModel(models.Model):
        # your fields
        my_placeholder = PlaceholderField('placeholder_name')
        # your methods


The :class:`~cms.models.fields.PlaceholderField` has one required parameter, a string ``slotname``.

The ``slotname`` is used in templates, to determine where the placeholder's plugins should appear
in the page, and in the placeholder configuration :setting:`CMS_PLACEHOLDER_CONF`, which determines
which plugins may be inserted into this placeholder.

You can also use a callable for the ``slotname``, as in::

    from django.db import models
    from cms.models.fields import PlaceholderField

    def my_placeholder_slotname(instance):
        return 'placeholder_name'

    class MyModel(models.Model):
        # your fields
        my_placeholder = PlaceholderField(my_placeholder_slotname)
        # your methods

.. warning::

    For security reasons the related_name for a
    :class:`~cms.models.fields.PlaceholderField` may not be suppressed using
    ``'+'``; this allows the cms to check permissions properly. Attempting to do
    so will raise a :exc:`ValueError`.

.. note::

    If you add a PlaceholderField to an existing model, you'll be able to see
    the placeholder in the frontend editor only after saving the relevant instance.

Admin Integration
=================

.. versionchanged:: 3.0

Your model with ``PlaceholderFields`` can still be edited in the admin. However, any
PlaceholderFields in it will **only be available for editing from the frontend**.
``PlaceholderFields`` **must** not be present in any ``fieldsets``, ``fields``, ``form`` or other
``ModelAdmin`` field's definition attribute.

To provide admin support for a model with a ``PlaceholderField`` in your application's admin, you
need to use the mixin :class:`~cms.admin.placeholderadmin.PlaceholderAdminMixin` along with the
:class:`~django.contrib.admin.ModelAdmin`.

.. note::

    Using this mixin is mandatory for permission check to work properly.

Note that the ``PlaceholderAdminMixin`` **must** precede
the ``ModelAdmin`` in the class definition::

    from django.contrib import admin
    from cms.admin.placeholderadmin import PlaceholderAdminMixin
    from myapp.models import MyModel

    class MyModelAdmin(PlaceholderAdminMixin, admin.ModelAdmin):
{'fraction_non_alphanumeric': 0.11183119819140919, 'fraction_numerical': 0.0012057272042200451, 'mean_word_length': 4.590564448188711, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6584936', 'n_tokens_mistral': 1757, 'n_tokens_neox': 1678, 'n_words': 722}