Index: ctools_plugin_example/ctools_plugin_example.info
===================================================================
--- ctools_plugin_example/ctools_plugin_example.info (revision 0)
+++ ctools_plugin_example/ctools_plugin_example.info (revision 0)
@@ -0,0 +1,8 @@
+name = Chaos Tools (Ctools) Plugin Example
+description = Shows how an external module can provide ctools plugins (for Panels, etc.).
+package = Chaos tool suite
+dependencies[] = ctools
+dependencies[] = panels
+dependencies[] = page_manager
+dependencies[] = advanced_help
+core = 6.x
Index: ctools_plugin_example/ctools_plugin_example.module
===================================================================
--- ctools_plugin_example/ctools_plugin_example.module (revision 0)
+++ ctools_plugin_example/ctools_plugin_example.module (revision 0)
@@ -0,0 +1,96 @@
+ 'Ctools Plugin Example',
+ 'description' => t("Demonstration code, advanced help, and a demo panel to show how to build ctools plugins."),
+ 'page callback' => 'ctools_plugin_example_explanation_page',
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_NORMAL_ITEM,
+ );
+
+ return $items;
+}
+
+
+/**
+ * Implementation of hook_ctools_plugin_directory().
+ * It simply tells panels where to find the .inc files that define various args, contexts, content_types
+ * In this case the subdirectories of ctools_plugin_example/panels are used
+ */
+function ctools_plugin_example_ctools_plugin_directory($module, $plugin) {
+ if ($module == 'ctools' && !empty($plugin)) {
+ return "plugins/$plugin";
+ }
+}
+
+
+/**
+ * Implement hook_ctools_plugin_api().
+ * If you do this, Ctools will pick up default panels pages in
+ *
There is a demo panel demonstrating much of the functionality provided at + $demo_panel, and you can find documentation on the examples at $ctools_plugin_example_help. + Ctools itself provides documentation at $ctools_help. Mostly, though, the code itself + is intended to be the teacher. You can find it at $path.
+ +END; + return $content; + +} Index: ctools_plugin_example/ctools_plugin_example.pages_default.inc =================================================================== --- ctools_plugin_example/ctools_plugin_example.pages_default.inc (revision 0) +++ ctools_plugin_example/ctools_plugin_example.pages_default.inc (revision 0) @@ -0,0 +1,413 @@ +.pages_default.inc + * With this naming, no additional code needs to be provided. Ctools will just find the file. + * The name of the hook isWe can use access plugins to determine access to a page or visibility of the panes in a page. Basically, we just determine access based on configuration settings and the various contexts that are available to us.
+The arbitrary example in plugins/access/arg_length.inc determines access based on the length of the simplecontext argument. You can configure whether access should be granted if the simplecontext argument is greater or less than some number.
+Contexts are fundamental to Ctools, and they almost always start with an argument to a panels page, so we'll start there too.
+We first need to process an argument.
+We're going to work with a "Simplecontext" context type and argument, and then with a content type that displays it. So we'll start by with the Simplecontext argument plugin in plugins/arguments/simplecontext_arg.inc.
+Note that the name of the file (simplecontext_arg.inc) is built from the machine name of our plugin (simplecontext_arg). And note also that the primary function that we use to provide our argument (ctools_plugin_example_simplecontext_arg_ctools_arguments()) is also built from the machine name. This magic is most of the naming magic that you have to know.
+You can browse plugins/arguments/simplecontext_arg.inc and see the little that it does.
+This demonstration module is intended for developers to look at and play with. Ctools plugins are not terribly difficult to do, but it can be hard to sort through the various arguments and required functions. The idea here is that you should have a starting point for most anything you want to do. Just work through the example, and then start experimenting with changing it.
+There are two parts to this demo:
+First, there is a sample panel provided that uses all the various plugins. It's at ctools_example/12345. You can edit the panel and configure all the panes on it.
+Second, the code is there for you to experiment with and change as you see fit. Sometimes starting with simple code and working with it can take you places that it's hard to go when you're looking at more complex examples.
+Now we get to the heart of the matter: Building a content type plugin. A content type plugin uses the contexts available to it to display something. plugins/content_types/simplecontext_content_type.inc does this work for us.
+Note that our content type also has an edit form which can be used to configure its behavior. This settings form is accessed through the panels interface, and it's up to you what the settings mean to the code and the generation of content in the display rendering.
+Now that we have a plugin for a simplecontext argument, we can create a plugin for a simplecontext context.
+Normally, a context would take an argument which is a key like a node ID (nid) and retrieve a more complex object from a database or whatever. In our example, we'll artificially transform the argument into an arbitrary "context" data object.
+plugins/contexts/simplecontext.inc implements our context.
+Note that there are actually two ways to create a context. The normal one, which we've been referring to, is to create a context from an argument. However, it is also possible to configure a context in a panel using the panels interface. This is quite inflexible, but might be useful for configuring single page. However, it means that we have a settings form for exactly that purpose. Our context would have to know how to create itself from a settings form as well as from an argument. Simplecontext can do that.
+Your module must provide a few things so that your plugins can be found.
+First, you need to implement hook_ctools_plugin_directory(). Here we're telling Ctools that our plugins will be found in the module's directory in the plugins/<plugintype> directory. Context plugins will be in ctools_plugin_example/plugins/contexts, Content-type plugins will be in ctools_plugin_example/plugins/content_types.
+<?php
function ctools_plugin_example_ctools_plugin_directory($module, $plugin) {
if ($module == 'ctools' && !empty($plugin)) {
return "plugins/$plugin";
}
}
?>Second, if you module wants to provide default panels pages, you can implement hook_ctools_plugin_api(). Ctools will then pick up your panels pages in the file named <modulename>.pages_default.inc.
+<?php
function ctools_plugin_example_ctools_plugin_api($module, $api) {
if ($module == 'panels_mini' && $api == 'panels_default') {
return array('version' => 1);
}
if ($module == 'page_manager' && $api == 'pages_default') {
return array('version' => 1);
}
}
?>Often a single data type can lead us to other data types. For example, a node has a user (the author) and the user has data associated with it.
+A relationship plugin allows this kind of data to be accessed.
+An example relationship plugin is provided in plugins/relationships/relcontext_from_simplecontext.inc. It looks at a simplecontext (which we got from an argument) and builds an (artificial) "relcontext" from that.
+