##############
API References
##############

*******
cms.api
*******

Python APIs for creating CMS contents. This is done in :mod:`cms.api` and not
on the models and managers, because the direct API via models and managers is
slightly counterintuitive for developers. Also the functions defined in this
module do sanity checks on arguments.
    
.. warning:: None of the functions in this module does any security or permission
             checks. They verify their input values to be sane wherever
             possible, however permission checks should be implemented manually
             before calling any of these functions.

.. warning:: Due to potential circular dependency issues, it's recommended
             to import the api in the functions that uses its function.

             e.g. use:

             ::

                 def my_function():
                     from cms.api import api_function

                     api_function(...)

             instead of:

             ::

                 from cms.api import api_function

                 def my_function():
                     api_function(...)


Functions and constants
=======================

.. module:: cms.api

.. data:: VISIBILITY_ALL

    Used for the ``limit_menu_visibility`` keyword argument to
    :func:`create_page`. Does not limit menu visibility.


.. data:: VISIBILITY_USERS

    Used for the ``limit_menu_visibility`` keyword argument to
    :func:`create_page`. Limits menu visibility to authenticated users.


.. data:: VISIBILITY_STAFF

    Used for the ``limit_menu_visibility`` keyword argument to
    :func:`create_page`. Limits menu visibility to staff users.


.. function:: create_page(title, template, language, menu_title=None, slug=None, apphook=None, apphook_namespace=None, redirect=None, meta_description=None, meta_keywords=None, created_by='python-api', parent=None, publication_date=None, publication_end_date=None, in_navigation=False, soft_root=False, reverse_id=None, navigation_extenders=None, published=False, site=None, login_required=False, limit_visibility_in_menu=VISIBILITY_ALL, position="last-child")

    Creates a :class:`cms.models.pagemodel.Page` instance and returns it. Also
    creates a :class:`cms.models.titlemodel.Title` instance for the specified
    language.
    
    :param string title: Title of the page
    :param string template: Template to use for this page. Must be in :setting:`CMS_TEMPLATES`
    :param string language: Language code for this page. Must be in :setting:`django:LANGUAGES`
    :param string menu_title: Menu title for this page
    :param string slug: Slug for the page, by default uses a slugified version of *title*
    :param apphook: Application to hook on this page, must be a valid apphook
    :type apphook: string or :class:`cms.app_base.CMSApp` subclass
    :param string apphook_namespace: Name of the apphook namespace
    :param string redirect: URL redirect
    :param string meta_description: Description of this page for SEO
    :param string meta_keywords: Keywords for this page for SEO
    :param created_by: User that is creating this page
    :type created_by: string of :class:`django.contrib.auth.models.User` instance
    :param parent: Parent page of this page
    :type parent: :class:`cms.models.pagemodel.Page` instance
    :param datetime publication_date: Date to publish this page
    :param datetime publication_end_date: Date to unpublish this page
    :param bool in_navigation: Whether this page should be in the navigation or not
    :param bool soft_root: Whether this page is a softroot or not
    :param string reverse_id: Reverse ID of this page (for template tags)
    :param string navigation_extenders: Menu to attach to this page. Must be a valid menu
    :param bool published: Whether this page should be published or not
    :param site: Site to put this page on
    :type site: :class:`django.contrib.sites.models.Site` instance
    :param bool login_required: Whether users must be logged in or not to view this page
    :param limit_menu_visibility: Limits visibility of this page in the menu
    :type limit_menu_visibility: :data:`VISIBILITY_ALL` or :data:`VISIBILITY_USERS` or :data:`VISIBILITY_STAFF`
    :param string position: Where to insert this node if *parent* is given, must be ``'first-child'`` or ``'last-child'``
    :param string overwrite_url: Overwritten path for this page


.. function:: create_title(language, title, page, menu_title=None, slug=None, redirect=None, meta_description=None, meta_keywords=None, parent=None)
    
    Creates a :class:`cms.models.titlemodel.Title` instance and returns it.

    :param string language: Language code for this page. Must be in :setting:`django:LANGUAGES`
    :param string title: Title of the page
    :param page: The page for which to create this title
    :type page: :class:`cms.models.pagemodel.Page` instance
    :param string menu_title: Menu title for this page
    :param string slug: Slug for the page, by default uses a slugified version of *title*
    :param string redirect: URL redirect
    :param string meta_description: Description of this page for SEO
    :param string meta_keywords: Keywords for this page for SEO
    :param parent: Used for automated slug generation
    :type parent: :class:`cms.models.pagemodel.Page` instance
    :param string overwrite_url: Overwritten path for this page


.. function:: add_plugin(placeholder, plugin_type, language, position='last-child', target=None,  **data)

    Adds a plugin to a placeholder and returns it.

    :param placeholder: Placeholder to add the plugin to
    :type placeholder: :class:`cms.models.placeholdermodel.Placeholder` instance
    :param plugin_type: What type of plugin to add
    :type plugin_type: string or :class:`cms.plugin_base.CMSPluginBase` subclass, must be a valid plugin
    :param string language: Language code for this plugin, must be in :setting:`django:LANGUAGES`
    :param string position: Position to add this plugin to the placeholder, must be a valid django-mptt position
    :param target: Parent plugin. Must be plugin instance
    :param kwargs data: Data for the plugin type instance


.. function:: create_page_user(created_by, user, can_add_page=True, can_change_page=True, can_delete_page=True, can_recover_page=True, can_add_pageuser=True, can_change_pageuser=True, can_delete_pageuser=True, can_add_pagepermission=True, can_change_pagepermission=True, can_delete_pagepermission=True, grant_all=False) 
    
    Creates a page user for the user provided and returns that page user.
    
    :param created_by: The user that creates the page user
    :type created_by: :class:`django.contrib.auth.models.User` instance
    :param user: The user to create the page user from
    :type user: :class:`django.contrib.auth.models.User` instance
    :param bool can_*: Permissions to give the user
    :param bool grant_all: Grant all permissions to the user


.. function:: assign_user_to_page(page, user, grant_on=ACCESS_PAGE_AND_DESCENDANTS, can_add=False, can_change=False, can_delete=False, can_change_advanced_settings=False, can_publish=False, can_change_permissions=False, can_move_page=False, grant_all=False)
    
    Assigns a user to a page and gives them some permissions. Returns the 
    :class:`cms.models.permissionmodels.PagePermission` object that gets
    created.
    
    :param page: The page to assign the user to
    :type page: :class:`cms.models.pagemodel.Page` instance
    :param user: The user to assign to the page
    :type user: :class:`django.contrib.auth.models.User` instance
    :param grant_on: Controls which pages are affected
    :type grant_on: :data:`cms.models.permissionmodels.ACCESS_PAGE`, :data:`cms.models.permissionmodels.ACCESS_CHILDREN`, :data:`cms.models.permissionmodels.ACCESS_DESCENDANTS` or :data:`cms.models.permissionmodels.ACCESS_PAGE_AND_DESCENDANTS`
    :param can_*: Permissions to grant
    :param bool grant_all: Grant all permissions to the user
    

.. function:: publish_page(page, user, language)

    Publishes a page.
    
    :param page: The page to publish
    :type page: :class:`cms.models.pagemodel.Page` instance
    :param user: The user that performs this action
    :type user: :class:`django.contrib.auth.models.User` instance
    :param string language: The target language to publish to

.. function:: get_page_draft(page):

    Returns the draft version of a page, regardless if the passed in
    page is a published version or a draft version.

    :param page: The page to get the draft version
    :type page: :class:`cms.models.pagemodel.Page` instance
    :return page: draft version of the page

.. function:: copy_plugins_to_language(page, source_language, target_language, only_empty=True):

    Copy the plugins to another language in the same page for all the page
    placeholders.

    By default plugins are copied only if placeholder has no plugin for the target language; use ``only_empty=False`` to change this.

    .. warning:: This function skips permissions checks

    :param page: the page to copy
    :type page: :class:`cms.models.pagemodel.Page` instance
    :param string source_language: The source language code, must be in :setting:`django:LANGUAGES`
    :param string target_language: The source language code, must be in :setting:`django:LANGUAGES`
    :param bool only_empty: if False, plugin are copied even if plugins exists in the
     target language (on a placeholder basis).
    :return int: number of copied plugins

Example workflows
=================

Create a page called ``'My Page`` using the template ``'my_template.html'`` and
add a text plugin with the content ``'hello world'``. This is done in English::

    from cms.api import create_page, add_plugin
    
    page = create_page('My Page', 'my_template.html', 'en')
    placeholder = page.placeholders.get(slot='body')
    add_plugin(placeholder, 'TextPlugin', 'en', body='hello world')


*************
cms.constants
*************

.. module:: cms.constants

.. data:: TEMPLATE_INHERITANCE_MAGIC

    The token used to identify when a user selects "inherit" as template for a
    page.

.. data:: LEFT

    Used as a position indicator in the toolbar.

.. data:: RIGHT

    Used as a position indicator in the toolbar.

.. data:: REFRESH

    Constant used by the toolbar.



***************
cms.plugin_base
***************

.. module:: cms.plugin_base

.. class:: CMSPluginBase

    Inherits ``django.contrib.admin.options.ModelAdmin``.
        
    .. attribute:: admin_preview
    
        Defaults to ``False``, if ``True`` there will be a preview in the admin.
        
    .. attribute:: change_form_template

        Custom template to use to render the form to edit this plugin.    
    
    .. attribute:: form
    
        Custom form class to be used to edit this plugin.

    .. method:: get_plugin_urls(instance)

        Returns URL patterns for which the plugin wants to register views for.
        They are included under django CMS PageAdmin in the plugin path
        (e.g.: ``/admin/cms/page/plugin/<plugin-name>/`` in the default case).
        Useful if your plugin needs to asynchronously talk to the admin.

    .. attribute:: model

        Is the :class:`CMSPlugin` model we created earlier. If you don't need
        model because you just want to display some template logic, use
        :class:`CMSPlugin` from :mod:`cms.models` as the model instead.
        
    .. attribute:: module

        Will group the plugin in the plugin editor. If module is ``None``,
        plugin is grouped "Generic" group.
    
    .. attribute:: name
        
        Will be displayed in the plugin editor.
        
    .. attribute:: render_plugin
    
        If set to ``False``, this plugin will not be rendered at all.
        
    .. attribute:: render_template
    
        Will be rendered with the context returned by the render function.
        
    .. attribute:: text_enabled
    
        Whether this plugin can be used in text plugins or not.
        
    .. method:: icon_alt(instance)
        
        Returns the alt text for the icon used in text plugins, see
        :meth:`icon_src`. 
        
    .. method:: icon_src(instance)
    
        Returns the url to the icon to be used for the given instance when that
        instance is used inside a text plugin.
        
    .. method:: render(context, instance, placeholder)
    
        This method returns the context to be used to render the template
        specified in :attr:`render_template`.
        
        :param context: Current template context.
        :param instance: Plugin instance that is being rendered.
        :param placeholder: Name of the placeholder the plugin is in.
        :rtype: ``dict``


.. _toolbar-api-reference:

***********
cms.toolbar
***********


All methods taking a ``side`` argument expect either
:data:`cms.constants.LEFT` or :data:`cms.constants.RIGHT` for that
argument.

Methods accepting the ``position`` argument can insert items at a specific
position. This can be either ``None`` to insert at the end, an integer
index at which to insert the item, a :class:`cms.toolbar.items.ItemSearchResult` to insert
it *before* that search result or a :class:`cms.toolbar.items.BaseItem` instance to insert
it *before* that item.


cms.toolbar.toolbar
===================

.. module:: cms.toolbar.toolbar


.. class:: CMSToolbar

    The toolbar class providing a Python API to manipulate the toolbar. Note
    that some internal attributes are not documented here.

    All methods taking a ``position`` argument expect either
    :data:`cms.constants.LEFT` or :data:`cms.constants.RIGHT` for that
    argument.

    This class inherits :class:`cms.toolbar.items.ToolbarMixin`, so please
    check that reference as well.

    .. attribute:: is_staff

        Whether the current user is a staff user or not.

    .. attribute:: edit_mode

        Whether the toolbar is in edit mode.

    .. attribute:: build_mode

        Whether the toolbar is in build mode.

    .. attribute:: show_toolbar

        Whether the toolbar should be shown or not.

    .. attribute:: csrf_token

        The CSRF token of this request

    .. attribute:: toolbar_language

        Language used by the toolbar.

    .. method:: add_item(item, position=None)

        Low level API to add items.

        Adds an item, which must be an instance of
        :class:`cms.toolbar.items.BaseItem`, to the toolbar.

        This method should only be used for custom item classes, as all builtin
        item classes have higher level APIs.

        Read above for information on ``position``.

    .. method:: remove_item(item)

        Removes an item from the toolbar or raises a :exc:`KeyError` if it's
        not found.

    .. method:: get_or_create_menu(key. verbose_name, side=LEFT, position=NOne)

        If a menu with ``key`` already exists, this method will return that
        menu. Otherwise it will create a menu for that ``key`` with the given
        ``verbose_name`` on ``side`` at ``position`` and return it.

    .. method:: add_button(name, url, active=False, disabled=False, extra_classes=None, extra_wrapper_classes=None, side=LEFT, position=None)

        Adds a button to the toolbar. ``extra_wrapper_classes`` will be applied
        to the wrapping ``div`` while ``extra_classes`` are applied to the
        ``<a>``.

    .. method:: add_button_list(extra_classes=None, side=LEFT, position=None)

        Adds an (empty) button list to the toolbar and returns it. See
        :class:`cms.toolbar.items.ButtonList` for further information.


cms.toolbar.items
=================

.. module:: cms.toolbar.items


.. class:: ItemSearchResult

    Used for the find APIs in :class:`ToolbarMixin`. Supports addition and
    subtraction of numbers. Can be cast to an integer.

    .. attribute:: item

        The item found.

    .. attribute:: index

        The index of the item.

.. class:: ToolbarMixin

    Provides APIs shared between :class:`cms.toolbar.toolbar.CMSToolbar` and
    :class:`Menu`.

    The ``active`` and ``disabled`` flags taken by all methods of this class
    specify the state of the item added.

    ``extra_classes`` should be either ``None`` or a list of class names as
    strings.

    .. attribute:: REFRESH_PAGE

        Constant to be used with ``on_close`` to refresh the current page when
        the frame is closed.

    .. attribute:: LEFT

        Constant to be used with ``side``.

    .. attribute:: RIGHT

        Constant to be used with ``side``.

    .. method:: get_item_count

        Returns the number of items in the toolbar or menu.

    .. method:: add_item(item, position=None)

        Low level API to add items, adds the ``item`` to the toolbar or menu
        and makes it searchable. ``item`` must be an instance of
        :class:`BaseItem`. Read above for information about the ``position``
        argument.

    .. method:: remove_item(item)

        Removes ``item`` from the toolbar or menu. If the item can't be found,
        a :exc:`KeyError` is raised.

    .. method:: find_items(item_type, **attributes)

        Returns a list of :class:`ItemSearchResult` objects matching all items
        of ``item_type``, which must be a subclass of :class:`BaseItem`, where
        all attributes in ``attributes`` match.

    .. method:: find_first(item_type, **attributes)

        Returns the first :class:`ItemSearchResult` that matches the search or
        ``None``. The search strategy is the same as in :meth:`find_items`.
        Since positional insertion allows ``None``, it's safe to use the return
        value of this method as the position argument to insertion APIs.

    .. method:: add_sideframe_item(name, url, active=False, disabled=False, extra_classes=None, on_close=None, side=LEFT, position=None)

        Adds an item which opens ``url`` in the side frame and returns it.

        ``on_close`` can be set to ``None`` to do nothing when the side frame
        closes, :attr:`REFRESH_PAGE` to refresh the page when it
        closes or a URL to open once it closes.

    .. method:: add_modal_item(name, url, active=False, disabled=False, extra_classes=None, on_close=REFRESH_PAGE, side=LEFT, position=None)

        The same as :meth:`add_sideframe_item`, but opens the ``url`` in a
        modal dialog instead of the side frame.

        ``on_close`` can be set to ``None`` to do nothing when the side modal
        closes, :attr:`REFRESH_PAGE` to refresh the page when it
        closes or a URL to open once it closes.

        Note: The default value for ``on_close`` is different in :meth:`add_sideframe_item` then in :meth:`add_modal_item`

    .. method:: add_link_item(name, url, active=False, disabled=False, extra_classes=None, side=LEFT, position=None)

        Adds an item that simply opens ``url`` and returns it.

    .. method:: add_ajax_item(name, action, active=False, disabled=False, extra_classes=None, data=None, question=None, side=LEFT, position=None)

        Adds an item which sends a POST request to ``action`` with ``data``.
        ``data`` should be ``None`` or a dictionary, the CSRF token will
        automatically be added to it.

        If ``question`` is set to a string, it will be asked before the
        request is sent to confirm the user wants to complete this action.


.. class:: BaseItem(position)

    Base item class.

    .. attribute:: template

        Must be set by subclasses and point to a Django template

    .. attribute:: side

        Must be either :data:`cms.constants.LEFT` or
        :data:`cms.constants.RIGHT`.

    .. method:: render()

        Renders the item and returns it as a string. By default calls
        :meth:`get_context` and renders :attr:`template` with the context
        returned.

    .. method:: get_context()

        Returns the context (as dictionary) for this item.


.. class:: Menu(name, csrf_token, side=LEFT, position=None)

    The menu item class. Inherits :class:`ToolbarMixin` and provides the APIs
    documented on it.

    The ``csrf_token`` must be set as this class provides high level APIs to
    add items to it.

    .. method:: get_or_create_menu(key, verbose_name, side=LEFT, position=None)

        The same as :meth:`cms.toolbar.toolbar.CMSToolbar.get_or_create_menu` but adds
        the menu as a sub menu and returns a :class:`SubMenu`.

    .. method:: add_break(identifier=None, position=None)

        Adds a visual break in the menu, useful for grouping items, and
        returns it. ``identifier`` may be used to make this item searchable.


.. class:: SubMenu(name, csrf_token, side=LEFT, position=None)

    Same as :class:`Menu` but without the :meth:`Menu.get_or_create_menu` method.


.. class:: LinkItem(name, url, active=False, disabled=False, extra_classes=None, side=LEFT)

    Simple link item.


.. class:: SideframeItem(name, url, active=False, disabled=False, extra_classes=None, on_close=None, side=LEFT)

    Item that opens ``url`` in side frame.


.. class:: AjaxItem(name, action, csrf_token, data=None, active=False, disabled=False, extra_classes=None, question=None, side=LEFT)

    An item which posts ``data`` to ``action``.


.. class:: ModalItem(name, url, active=False, disabled=False, extra_classes=None, on_close=None, side=LEFT)

    Item that opens ``url`` in the modal.


.. class:: Break(identifier=None)

    A visual break for menus. ``identifier`` may be provided to make this item
    searchable. Since breaks can only be within menus, they have no ``side``
    attribute.


.. class:: ButtonList(identifier=None, extra_classes=None, side=LEFT)

    A list of one or more buttons.

    The ``identifier`` may be provided to make this item searchable.

    .. method:: add_item(item)

        Adds ``item`` to the list of buttons. ``item`` must be an instance of
        :class:`Button`.

    .. method:: add_button(name, url, active=False, disabled=False, extra_classes=None)

        Adds a :class:`Button` to the list of buttons and returns it.


.. class:: Button(name, url, active=False, disabled=False, extra_classes=None)

    A button to be used with :class:`ButtonList`. Opens ``url`` when clicked.


**********
menus.base
**********

.. module:: menus.base

.. class:: NavigationNode(title, url, id[, parent_id=None][, parent_namespace=None][, attr=None][, visible=True])

    A navigation node in a menu tree.
        
    :param string title: The title to display this menu item with.
    :param string url: The URL associated with this menu item.
    :param id: Unique (for the current tree) ID of this item.
    :param parent_id: Optional, ID of the parent item.
    :param parent_namespace: Optional, namespace of the parent.
    :param dict attr: Optional, dictionary of additional information to store on
                      this node.
    :param bool visible: Optional, defaults to ``True``, whether this item is
                         visible or not.


    .. method:: get_descendants

        Returns a list of all children beneath the current menu item.

    .. method:: get_ancestors

        Returns a list of all parent items, excluding the current menu item.

    .. method:: get_absolute_url

        Utility method to return the URL associated with this menu item,
        primarily to follow naming convention asserted by Django.

    .. method:: get_menu_title

        Utility method to return the associated title, using the same naming
        convention used by :class:`cms.models.pagemodel.Page`.


