Remember - although grouping the callbacks defined in these properties into the same .inc file can be handy, you're not bound to doing so. If you have a visibility checker that you want to share across a lot of content types, for example, consider defining the visibility checker in the main .module file while keeping the rest of the plugin in its own .inc file.
Some unnecessary duplication and inelegancies persist in the logic behind content type plugin properties; this is particularly noteworthy in the case of the add/edit property distinctions. These issues are allowed to persist largely for legacy compatibility reasons.
Plugin declaration functions must adhere to a particular naming convention; see panels_get_directories() for details. \n Note that the \pdarray provided by this sample does NOT define a coherent, working content type; displaying the full range of the plugin's flexibility makes it impossible to do so. For working examples, see the various plugins defined in the panels/content_types directory.
@SECplug{content_types,pdfunc,Content Type Plugin Declaration}This sample \pdfunc returns a definition array containing ALL of the \plugprops that Panels currently allows. The string used for the array key is significant: it determines the 'type' that panes which are created by this plugin will be assigned.
Keep in mind when choosing a type name that namespace collisions are both silent and destructive (the Panels engine will not emit any errors, it will simply overwrite data). Such collisions will always be decided in favor of the last plugin processed; processing order order is generally determined by the weight of the module (in the system table) defining the plugin.
All the plugins that come packaged with Panels necessarily obey a strict naming convention: the array key used for $items is the same as the name of the file itself, as well as being the same as the string prefixed by the module name (in this case, 'panels_'), and affixed by a string that indicates the type of plugin (in this case, 'panels_content_types'). Your modules need not follow the same conventions, although it is recommended that you do if possible; again, refer to panels_get_directories().
@code function panels_SAMPLE_CT_panels_content_types() { $items['SAMPLE_CT'] = array( 'title' => t('Sample Content Type'), 'weight' => -10, 'single' => TRUE, 'content_types' => 'panels_admin_content_types_SAMPLE_CT', 'render callback' => 'panels_content_SAMPLE_CT', 'add callback' => 'panels_admin_add_SAMPLE_CT', 'edit callback' => 'panels_admin_edit_SAMPLE_CT', 'add validate callback' => 'panels_admin_validate_SAMPLE_CT', 'edit validate callback' => 'panels_admin_validate_SAMPLE_CT', 'add submit callback' => 'panels_admin_submit_SAMPLE_CT', 'edit submit callback' => 'panels_admin_submit_SAMPLE_CT', 'title callback' => 'panels_admin_title_SAMPLE_CT', 'editor render callback' => 'panels_admin_pane_render_SAMPLE_CT', 'render last' => TRUE, 'visibility control' => 'panels_admin_visibility_control_SAMPLE_CT', 'visibility submit' => 'panels_admin_visibility_submit_SAMPLE_CT', 'visibility check' => 'panels_content_visibility_check_SAMPLE_CT', 'visibility serialize' => TRUE, 'role-based access' => FALSE, 'roles and visibility' => TRUE, 'form control' => 'panels_admin_form_control_SAMPLE_CT', ); return $items; } @endcode \n\n @SSECplug{content_types,pdfunc,setprops,Overview of Setting Properties}Only a few of the twenty properties defined for content type plugins are required, and some of them have default values that Panels will set if you don't assign anything. This first table covers setting properties. Keep in mind that although these tables indicate that there are requirements and interdependencies among the properties, there are no systematic checks to ensure that a plugin meets the requirements. Panels simply assumes that you did it right.
\nProperty Name | Data Type | Required? | Default Value | Dependencies | Notes |
@AAP{content_types,title,title} | string | Yes | None | The title that will be used for this pane on the 'Add Content' modal form, and in the display content editor in general. This is a purely internal setting; normal users will never see it. | |
@AAP{content_types,weight,weight} | Integer | No | \c 0 | None | Standard drupal weighting concept at work here; all it determines is the position of this content type's icon relative to the other content type icons on the general Panels configuration forms. See panels_common_settings(). |
@AAP{content_types,single,single} | Boolean | No | \c FALSE | None | Indicates that this content type plugin provides only a single content type. Currently, this setting is ONLY used in figuring out how to group the content type on the general Panels configuration forms; see panels_common_settings(). Check out panels_admin_content_types_block() for an example of how one plugin can used define multiple content types (technically, multiple subtypes) |
@AAP{content_types,render-last,render last} | Boolean | No | FALSE1 | none | If set to \c TRUE, this pane will be pushed to the back of the line during the render routine. See panels_render_panes(). |
@AAP{content_types,visibility-serialize,visibility serialize} | Boolean | Yes2,3 | FALSE | @LAP{content_types,t-visibility-control,visibility control} | If \c TRUE, then contents of $pane->visibility will be serialized before being saved to the database. This should be set as \c TRUE if, for example, your visibility form widget uses checkboxes (and therefore generates an array), as opposed to if your widget uses radios (and therefore generates an integer that can be stored directly). See panels_content_config_form_submit() and panels_save_display() to better understand how this works. |
@AAP{content_types,role-based-access,role-based access} | Boolean | No | TRUE4 | none | Boolean setting to indicate whether you want the your content type to utilize the Panels API's built-in access system, which is based on drupal user roles. Set this to FALSE to disable role-based access. |
@AAP{content_types,roles-and-visibility,roles and visibility} | Boolean | No | FALSE1 | @LAP{content_types,t-visibility-control,visibility control} | If you want your content type to use both your custom visibility logic and Panels' built-in roles-based access system, then set this to TRUE. Setting 'role-based access' to TRUE is not sufficient; see panels_ajax_ct_preconfigure() to understand how this works. If you use both systems, panels_pane_access() will \c AND the results together when determining pane visibility. |
This table provides a basic summary for all thirteen @LGt{p-p-callback,callback properties}. Most of the properties also have detailed documentation, which can be reached by clicking the property name.
Parameters that are passed by reference from the function side (through call_user_func_array()) are marked with the by-reference operator.
\attention apis may break. here's how they're likely to. be warned. \attention form control is the most subject to change. \note 'required' and 'dependencies' have specific meanings.Property Name | Return Value Type | Required? | Dependencies | Parameters | Notes |
@LAP{content_types,callbacks_content_types,content_types}@AAP{content_types,t-content_types, } | Array | Yes | None | Panels calls this function to find out how many content types this plugin provides, as well as some basic 'gatekeeper' information about each of those content types. Most importantly, optional and required context(s) are defined in this function. | |
@LAP{content_types,callbacks_render-callback,render callback}@AAP{content_types,t-render-callback, } | Object | Yes | None | $pane->configuration1, $panel_args, $context | Panels calls this function while preparing a @LGt{display,display object} for viewing. The callback needs to construct and return an object, which is passed along to the @LAP{styles,Style} and @LAP{layouts,Layout} plugins for handling. |
@LAP{content_types,callbacks_add-callback,add callback}@AAP{content_types,t-add-callback, } | FAPI Array | No | None | $subtype, $parents, $pane->configuration1,2 | This function gets called when the user clicks an icon to add a new pane (from the 'Add Content' @LGt{modal,modal form}). note that it is often possible to use the same, or nearly the same, callback for this as for the @LAP{content_types,callbacks_edit-callback,edit callback}. |
@LAP{content_types,callbacks_edit-callback,edit callback}@AAP{content_types,t-edit-callback, } | FAPI Array | No | None | $subtype, $parents, $pane->configuration | This function gets called when the user clicks the 'Configure' button on an already-existing pane; it partially governs what appears on the resulting configuration modal. |
@LAP{content_types,callbacks_addedit-validate-callback,add/edit validate callback}@AAP{content_types,t-addedit-validate-callback, } | No | None3 | $form, $form_values | Defines a callback to be used as a FAPI validator, but only for the $form_values set by form items defined in the @LAP{content_types,callbacks_edit-callback,add/edit callback}. | |
@LAP{content_types,callbacks_addedit-submit-callback,add/edit submit callback}@AAP{content_types,t-addedit-submit-callback, } | part of the $pane->configuration Array | No | None3 | $form_values | Defines a callback to be used as a FAPI submit handler, but only for the $form_values set by form items defined in the @LAP{content_types,callbacks_edit-callback,add/edit callback}. |
@LAP{content_types,callbacks_title-callback,title callback}@AAP{content_types,t-title-callback, } | String | Yes | None | $pane->configuration, $context | This function determines the title that the pane will use in the display content editor, and ONLY that title. |
@LAP{content_types,callbacks_editor-render-callback,editor render callback}@AAP{content_types,t-editor-render-callback, } | String | No | None | $display, $pane | This function determines the title that the pane will use in the display content editor, and ONLY that title. |
@LAP{content_types,callbacks_visibility-control,visibility control}@AAP{content_types,t-visibility-control, } | FAPI Array | No | None | $contexts, $subtype, $pane->configuration, $add | This callback is fired shortly after the add/edit callbacks. Use it to create a form widget form widget from which the user can select values that will make sense when passed to your @LAP{content_types,callbacks_visibility-check,visibility check callback}. |
@LAP{content_types,callbacks_visibility-submit,visibility submit}@AAP{content_types,t-visibility-submit, } | Mixed | No | @LAP{content_types,callbacks_visibility-control,visibility control} | $contexts, $subtype, $pane->configuration, $add | The custom submit handler for your content type's visibility settings. This function is passed the portion of the $form_values array that was generated from the widgets created by the @LAP{content_types,callbacks_visibility-control,visibility control} callback. Most plugins won't need to define this property, even if they define custom visibility control. |
@LAP{content_types,callbacks_visibility-check,visibility check}@AAP{content_types,t-visibility-check, } | Boolean | Yes4 | @LAP{content_types,callbacks_visibility-control,visibility control} | $contexts, $subtype, $pane->configuration, $add | Panels calls this function during the pane accessibility checking routine, which is handled by primarily by panels_pane_access(). Define the logic governing your content type's visibility here. |
@LAP{content_types,callbacks_form-control,form control}@AAP{content_types,t-form-control, } | FAPI $form Array | No | None | &$form, &$pane, &$display | If the other callbacks governing the add/edit form (i.e., the @LAP{content_types,callbacks_edit-callback,add/edit callback} properties or the @LAP{content_types,callbacks_visibility-control,visibility control} property) aren't enough for your needs, then implement this callback. This function is passed virtually all of the Panels editing data by reference. Use with caution. |