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 + * .pages_default.inc + */ +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); + } +} + +/** + * Just provide an explanation page for the admin section + * @return unknown_type + */ +function ctools_plugin_example_explanation_page() { + $demo_panel = l("Ctools Demo Panel",'ctools_plugin_example/xxxxx'); + $ctools_help = theme('advanced_help_topic', 'ctools', 'plugins', 'title'); + $ctools_plugin_example_help = theme('advanced_help_topic','ctools_plugin_example','Chaos-Tools--Ctools--Plugin-Examples','title'); + $path = drupal_get_path('module','ctools_plugin_example'); + $content .= <<The Ctools Plugin Example is simply a developer's demo of how to create plugins for Ctools. + It provides no useful functionality for an ordinary user. +

+

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 is _default_page_manager_pages() + * + * Although this example only provides one page, the returned array could + * have several pages. + * + * @return none + */ + +function ctools_plugin_example_default_page_manager_pages() { + $page = new stdClass; + $page->disabled = FALSE; /* Edit this to true to make a default page disabled initially */ + $page->api_version = 1; + $page->name = 'ctools_plugin_example'; + $page->task = 'page'; + $page->admin_title = 'Ctools Plugin Example'; + $page->admin_description = 'This panel provides no functionality to a working Drupal system. It\'s intended to display the various sample plugins provided by the Ctools Plugin Example module. '; + $page->path = 'ctools_plugin_example/%sc'; + $page->access = array( + 'logic' => 'and', + ); + $page->menu = array( + 'type' => 'normal', + 'title' => 'Ctools Plugin Example', + 'name' => 'navigation', + 'weight' => '0', + 'parent' => array( + 'type' => 'none', + 'title' => '', + 'name' => 'navigation', + 'weight' => '0', + ), + ); + $page->arguments = array( + 'sc' => array( + 'id' => 2, + 'identifier' => 'simplecontext-arg', + 'name' => 'simplecontext_arg', + 'settings' => array(), + ), + ); + $page->conf = array(); + $page->default_handlers = array(); + $handler = new stdClass; + $handler->disabled = FALSE; /* Edit this to true to make a default handler disabled initially */ + $handler->api_version = 1; + $handler->name = 'page_ctools_panel_context'; + $handler->task = 'page'; + $handler->subtask = 'ctools_plugin_example'; + $handler->handler = 'panel_context'; + $handler->weight = 0; + $handler->conf = array( + 'title' => 'Panel', + 'no_blocks' => FALSE, + 'css_id' => '', + 'css' => '', + 'contexts' => array( + '0' => array( + 'name' => 'simplecontext', + 'id' => 1, + 'identifier' => 'Configured Simplecontext (not from argument)', + 'keyword' => 'configured_simplecontext', + 'context_settings' => array( + 'sample_simplecontext_setting' => 'default simplecontext setting', + ), + ), + ), + 'relationships' => array( + '0' => array( + 'context' => 'argument_simplecontext_arg_2', + 'name' => 'relcontext_from_simplecontext', + 'id' => 1, + 'identifier' => 'Relcontext from Simplecontext (from relationship)', + 'keyword' => 'relcontext', + ), + ), + 'access' => array( + 'logic' => 'and', + ), + ); + $display = new panels_display; + $display->layout = 'threecol_33_34_33_stacked'; + $display->layout_settings = array(); + $display->panel_settings = array( + 'style' => 'rounded_corners', + 'style_settings' => array( + 'default' => array( + 'corner_location' => 'pane', + ), + ), + ); + $display->cache = array(); + $display->title = 'Ctools Plugin Example Panel'; + $display->hide_title = FALSE; + $display->content = array(); + $display->panels = array(); + $pane = new stdClass; + $pane->pid = 'new-1'; + $pane->panel = 'left'; + $pane->type = 'no_context_content_type'; + $pane->subtype = 'no_context_content_type'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'item1' => 'contents of config item 1', + 'item2' => 'contents of config item 2', + 'override_title' => 0, + 'override_title_text' => '', + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 0; + $display->content['new-1'] = $pane; + $display->panels['left'][0] = 'new-1'; + $pane = new stdClass; + $pane->pid = 'new-2'; + $pane->panel = 'left'; + $pane->type = 'custom'; + $pane->subtype = 'custom'; + $pane->shown = TRUE; + $pane->access = array( + 'plugins' => array( + '0' => array( + 'name' => 'arg_length', + 'settings' => array( + 'greater_than' => '1', + 'arg_length' => '4', + ), + 'context' => 'argument_simplecontext_arg_2', + ), + ), + ); + $pane->configuration = array( + 'title' => 'Long Arg Visibility Block', + 'body' => 'This block will be here when the argument is longer than configured arg length. It uses the \'arg_length\' access plugin to test against the length of the argument used for Simplecontext.', + 'format' => '1', + 'substitute' => 1, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 1; + $display->content['new-2'] = $pane; + $display->panels['left'][1] = 'new-2'; + $pane = new stdClass; + $pane->pid = 'new-3'; + $pane->panel = 'left'; + $pane->type = 'custom'; + $pane->subtype = 'custom'; + $pane->shown = TRUE; + $pane->access = array( + 'plugins' => array( + '0' => array( + 'name' => 'arg_length', + 'settings' => array( + 'greater_than' => '0', + 'arg_length' => '4', + ), + 'context' => 'argument_simplecontext_arg_2', + ), + ), + ); + $pane->configuration = array( + 'title' => 'Short Arg Visibility', + 'body' => 'This block appears when the simplecontext argument is less than the configured length.', + 'format' => '1', + 'substitute' => 1, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 2; + $display->content['new-3'] = $pane; + $display->panels['left'][2] = 'new-3'; + $pane = new stdClass; + $pane->pid = 'new-4'; + $pane->panel = 'middle'; + $pane->type = 'simplecontext_content_type'; + $pane->subtype = 'simplecontext_content_type'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'buttons' => NULL, + '#validate' => NULL, + '#submit' => NULL, + '#action' => NULL, + 'context' => 'argument_simplecontext_arg_2', + 'aligner_start' => NULL, + 'override_title' => 1, + 'override_title_text' => 'Simplecontext (with an arg)', + 'aligner_stop' => NULL, + 'override_title_markup' => NULL, + 'config_item_1' => 'Config item 1 contents', + '#build_id' => NULL, + '#type' => NULL, + '#programmed' => NULL, + 'form_build_id' => 'form-19c4ae6cb54fad8f096da46e95694e5a', + '#token' => NULL, + 'form_token' => '17141d3531eaa7b609da78afa6f3b560', + 'form_id' => 'simplecontext_content_type_edit_form', + '#id' => NULL, + '#description' => NULL, + '#attributes' => NULL, + '#required' => NULL, + '#tree' => NULL, + '#parents' => NULL, + '#method' => NULL, + '#post' => NULL, + '#processed' => NULL, + '#defaults_loaded' => NULL, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 0; + $display->content['new-4'] = $pane; + $display->panels['middle'][0] = 'new-4'; + $pane = new stdClass; + $pane->pid = 'new-5'; + $pane->panel = 'middle'; + $pane->type = 'simplecontext_content_type'; + $pane->subtype = 'simplecontext_content_type'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'buttons' => NULL, + '#validate' => NULL, + '#submit' => NULL, + '#action' => NULL, + 'context' => 'context_simplecontext_1', + 'aligner_start' => NULL, + 'override_title' => 1, + 'override_title_text' => 'Configured simplecontext content type (not from arg)', + 'aligner_stop' => NULL, + 'override_title_markup' => NULL, + 'config_item_1' => '(configuration for simplecontext)', + '#build_id' => NULL, + '#type' => NULL, + '#programmed' => NULL, + 'form_build_id' => 'form-d016200490abd015dc5b8a7e366d76ea', + '#token' => NULL, + 'form_token' => '17141d3531eaa7b609da78afa6f3b560', + 'form_id' => 'simplecontext_content_type_edit_form', + '#id' => NULL, + '#description' => NULL, + '#attributes' => NULL, + '#required' => NULL, + '#tree' => NULL, + '#parents' => NULL, + '#method' => NULL, + '#post' => NULL, + '#processed' => NULL, + '#defaults_loaded' => NULL, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 1; + $display->content['new-5'] = $pane; + $display->panels['middle'][1] = 'new-5'; + $pane = new stdClass; + $pane->pid = 'new-6'; + $pane->panel = 'right'; + $pane->type = 'relcontext_content_type'; + $pane->subtype = 'relcontext_content_type'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'buttons' => NULL, + '#validate' => NULL, + '#submit' => NULL, + '#action' => NULL, + 'context' => 'relationship_relcontext_from_simplecontext_1', + 'aligner_start' => NULL, + 'override_title' => 0, + 'override_title_text' => '', + 'aligner_stop' => NULL, + 'override_title_markup' => NULL, + 'config_item_1' => 'some stuff in this one', + '#build_id' => NULL, + '#type' => NULL, + '#programmed' => NULL, + 'form_build_id' => 'form-8485f84511bd06e51b4a48e998448054', + '#token' => NULL, + 'form_token' => '1c3356396374d51d7d2531a10fd25310', + 'form_id' => 'relcontext_edit_form', + '#id' => NULL, + '#description' => NULL, + '#attributes' => NULL, + '#required' => NULL, + '#tree' => NULL, + '#parents' => NULL, + '#method' => NULL, + '#post' => NULL, + '#processed' => NULL, + '#defaults_loaded' => NULL, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 0; + $display->content['new-6'] = $pane; + $display->panels['right'][0] = 'new-6'; + $pane = new stdClass; + $pane->pid = 'new-7'; + $pane->panel = 'top'; + $pane->type = 'custom'; + $pane->subtype = 'custom'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'title' => 'Demonstrating Ctools Plugins', + 'body' => 'The Ctools Plugin Example module (and this panel page) are just here to demonstrate how to build Ctools plugins. + + ', + 'format' => '2', + 'substitute' => 1, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 0; + $display->content['new-7'] = $pane; + $display->panels['top'][0] = 'new-7'; + $handler->conf['display'] = $display; + $page->default_handlers[$handler->name] = $handler; + + $pages['ctools_plugin_example_demo_page'] = $page; + /* ---------------------------- */ + + $page = new stdClass; + $page->disabled = FALSE; /* Edit this to true to make a default page disabled initially */ + $page->api_version = 1; + $page->name = 'ctools_plugin_example_base'; + $page->task = 'page'; + $page->admin_title = 'Ctools Plugin Example Base Page'; + $page->admin_description = 'This panel is for when people hit /ctools_plugin_example without an argument. We can use it to tell people to move on.'; + $page->path = 'ctools_plugin_example'; + $page->access = array(); + $page->menu = array(); + $page->arguments = array(); + $page->conf = array(); + $page->default_handlers = array(); + $handler = new stdClass; + $handler->disabled = FALSE; /* Edit this to true to make a default handler disabled initially */ + $handler->api_version = 1; + $handler->name = 'page_ctools_plugin_example_base_panel_context'; + $handler->task = 'page'; + $handler->subtask = 'ctools_plugin_example_base'; + $handler->handler = 'panel_context'; + $handler->weight = 0; + $handler->conf = array( + 'title' => 'Panel', + 'no_blocks' => FALSE, + 'css_id' => '', + 'css' => '', + 'contexts' => array(), + 'relationships' => array(), + ); + $display = new panels_display; + $display->layout = 'onecol'; + $display->layout_settings = array(); + $display->panel_settings = array(); + $display->cache = array(); + $display->title = ''; + $display->hide_title = FALSE; + $display->content = array(); + $display->panels = array(); + $pane = new stdClass; + $pane->pid = 'new-1'; + $pane->panel = 'middle'; + $pane->type = 'custom'; + $pane->subtype = 'custom'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'title' => 'Use this page with an argument', + 'body' => 'This demo page works if you use an argument, like ctools_plugin_example/xxxxx.', + 'format' => '1', + 'substitute' => NULL, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 0; + $display->content['new-1'] = $pane; + $display->panels['middle'][0] = 'new-1'; + $handler->conf['display'] = $display; + $page->default_handlers[$handler->name] = $handler; + $pages['base_page'] = $page; + + + + + return $pages; +} \ No newline at end of file Index: ctools_plugin_example/help/Access-Plugins--Determining-access-and-visibility.html =================================================================== --- ctools_plugin_example/help/Access-Plugins--Determining-access-and-visibility.html (revision 0) +++ ctools_plugin_example/help/Access-Plugins--Determining-access-and-visibility.html (revision 0) @@ -0,0 +1,17 @@ +
+ + + + +
+

We 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.

+
+ +
+
+
+ +
+ +
Index: ctools_plugin_example/help/Argument-Plugins--Starting-at-the-beginning.html =================================================================== --- ctools_plugin_example/help/Argument-Plugins--Starting-at-the-beginning.html (revision 0) +++ ctools_plugin_example/help/Argument-Plugins--Starting-at-the-beginning.html (revision 0) @@ -0,0 +1,20 @@ +
+ + + + +
+

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.

+
+ +
+
+
+ +
+ +
Index: ctools_plugin_example/help/Chaos-Tools--Ctools--Plugin-Examples.html =================================================================== --- ctools_plugin_example/help/Chaos-Tools--Ctools--Plugin-Examples.html (revision 0) +++ ctools_plugin_example/help/Chaos-Tools--Ctools--Plugin-Examples.html (revision 0) @@ -0,0 +1,19 @@ +
+ + + + +
+

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.

+
+ +
+
+
+ +
+ +
Index: ctools_plugin_example/help/Content-Type-Plugins--Displaying-content-using-a-context.html =================================================================== --- ctools_plugin_example/help/Content-Type-Plugins--Displaying-content-using-a-context.html (revision 0) +++ ctools_plugin_example/help/Content-Type-Plugins--Displaying-content-using-a-context.html (revision 0) @@ -0,0 +1,17 @@ +
+ + + + +
+

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.

+
+ +
+
+
+ +
+ +
Index: ctools_plugin_example/help/Context-plugins--Creating-a--context--from-an-argument.html =================================================================== --- ctools_plugin_example/help/Context-plugins--Creating-a--context--from-an-argument.html (revision 0) +++ ctools_plugin_example/help/Context-plugins--Creating-a--context--from-an-argument.html (revision 0) @@ -0,0 +1,19 @@ +
+ + + + +
+

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.

+
+ +
+
+
+ +
+ +
Index: ctools_plugin_example/help/Module-setup-and-hooks.html =================================================================== --- ctools_plugin_example/help/Module-setup-and-hooks.html (revision 0) +++ ctools_plugin_example/help/Module-setup-and-hooks.html (revision 0) @@ -0,0 +1,20 @@ +
+ + + + +
+

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);
  }
}
?>

+
+ +
+
+
+ +
+ +
Index: ctools_plugin_example/help/Relationships--Letting-one-context-take-us-to-another.html =================================================================== --- ctools_plugin_example/help/Relationships--Letting-one-context-take-us-to-another.html (revision 0) +++ ctools_plugin_example/help/Relationships--Letting-one-context-take-us-to-another.html (revision 0) @@ -0,0 +1,18 @@ +
+ + + + +
+

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.

+
+ +
+
+
+ +
+ +
Index: ctools_plugin_example/help/ctools_plugin_example.help.ini =================================================================== --- ctools_plugin_example/help/ctools_plugin_example.help.ini (revision 0) +++ ctools_plugin_example/help/ctools_plugin_example.help.ini (revision 0) @@ -0,0 +1,42 @@ +[Chaos-Tools--Ctools--Plugin-Examples] +title = Ctools Plugin Examples +file = Chaos-Tools--Ctools--Plugin-Examples +weight = 0 +parent = + +[Module-setup-and-hooks] +title = Module setup and hooks +file = Module-setup-and-hooks +weight = -15 +parent = Chaos-Tools--Ctools--Plugin-Examples + +[Argument-Plugins--Starting-at-the-beginning] +title = Argument Plugins: Starting at the beginning +file = Argument-Plugins--Starting-at-the-beginning +weight = -14 +parent = Chaos-Tools--Ctools--Plugin-Examples + +[Context-plugins--Creating-a--context--from-an-argument] +title = Context plugins: Creating a context from an argument +file = Context-plugins--Creating-a--context--from-an-argument +weight = -13 +parent = Chaos-Tools--Ctools--Plugin-Examples + +[Content-Type-Plugins--Displaying-content-using-a-context] +title = Content Type Plugins: Displaying content using a context +file = Content-Type-Plugins--Displaying-content-using-a-context +weight = -12 +parent = Chaos-Tools--Ctools--Plugin-Examples + +[Access-Plugins--Determining-access-and-visibility] +title = Access Plugins: Determining access and visibility +file = Access-Plugins--Determining-access-and-visibility +weight = -11 +parent = Chaos-Tools--Ctools--Plugin-Examples + +[Relationships--Letting-one-context-take-us-to-another] +title = Relationships: Letting one context take us to another +file = Relationships--Letting-one-context-take-us-to-another +weight = -10 +parent = Chaos-Tools--Ctools--Plugin-Examples + Index: ctools_plugin_example/plugins/panels.pages.inc =================================================================== --- ctools_plugin_example/plugins/panels.pages.inc (revision 0) +++ ctools_plugin_example/plugins/panels.pages.inc (revision 0) @@ -0,0 +1,215 @@ +pid = 'new'; + $page->did = 'new'; + $page->name = 'ctools_plugin_example_demo_panel'; + $page->title = 'Panels Plugin Example Demo Panel'; + $page->access = array(); + $page->path = 'demo_panel'; + $page->load_flags = 1; + $page->css_id = ''; + $page->arguments = array( + 0 => + array( + 'name' => 'simplecontext_arg', + 'id' => 1, + 'default' => '404', + 'title' => '', + 'identifier' => 'Simplecontext arg', + 'keyword' => 'simplecontext', + ), + ); + $page->relationships = array( + 0 => + array( + 'context' => 'argument_simplecontext_arg_1', + 'name' => 'relcontext_from_simplecontext', + 'id' => 1, + 'identifier' => 'Relcontext from Simplecontext', + 'keyword' => 'relcontext', + ), + ); + $page->no_blocks = '0'; + $page->switcher_options = array(); + $page->menu = '0'; + $page->contexts = array(); + $display = new ctools_display(); + $display->did = 'new'; + $display->layout = 'threecol_33_34_33_stacked'; + $display->layout_settings = array(); + $display->panel_settings = array(); + $display->content = array(); + $display->panels = array(); + $pane = new stdClass(); + $pane->pid = 'new-1'; + $pane->panel = 'left'; + $pane->type = 'custom'; + $pane->shown = '1'; + $pane->subtype = 'custom'; + $pane->access = array(); + $pane->configuration = array( + 'style' => 'default', + 'override_title' => 0, + 'override_title_text' => '', + 'css_id' => '', + 'css_class' => '', + 'title' => '"No Context Item"', + 'body' => 'The "no context item" content type is here to demonstrate that you can create a content_type that does not require a context. This is probably the same as just creating a custom php block on the fly, and might serve the same purpose.', + 'format' => '1', + ); + $pane->cache = array(); + $display->content['new-1'] = $pane; + $display->panels['left'][0] = 'new-1'; + $pane = new stdClass(); + $pane->pid = 'new-2'; + $pane->panel = 'left'; + $pane->type = 'no_context_item'; + $pane->shown = '1'; + $pane->subtype = 'description'; + $pane->access = array(); + $pane->configuration = array( + 'style' => 'default', + 'override_title' => 0, + 'override_title_text' => '', + 'css_id' => '', + 'css_class' => '', + 'item1' => 'one', + 'item2' => 'two', + 'item3' => 'three', + ); + $pane->cache = array(); + $display->content['new-2'] = $pane; + $display->panels['left'][1] = 'new-2'; + $pane = new stdClass(); + $pane->pid = 'new-3'; + $pane->panel = 'middle'; + $pane->type = 'custom'; + $pane->shown = '1'; + $pane->subtype = 'custom'; + $pane->access = array(); + $pane->configuration = array( + 'style' => 'default', + 'override_title' => 0, + 'override_title_text' => '', + 'css_id' => '', + 'css_class' => '', + 'title' => 'Simplecontext', + 'body' => 'The "Simplecontext" content and content type demonstrate a very basic context and how to display it. + + Simplecontext includes configuration, so it can get info from the config. It can also get its information to run from a simplecontext context, generated either from an arg to the panels page or via explicitly adding a context to the page.', + 'format' => '1', + ); + $pane->cache = array(); + $display->content['new-3'] = $pane; + $display->panels['middle'][0] = 'new-3'; + $pane = new stdClass(); + $pane->pid = 'new-4'; + $pane->panel = 'middle'; + $pane->type = 'simplecontext_item'; + $pane->shown = '1'; + $pane->subtype = 'description'; + $pane->access = array( + 0 => '2', + 1 => '4', + ); + $pane->configuration = array( + 'context' => 'argument_simplecontext_arg_1', + 'style' => 'default', + 'override_title' => 0, + 'override_title_text' => '', + 'css_id' => '', + 'css_class' => '', + 'config_item_1' => 'simplecontext called from arg', + ); + $pane->cache = array(); + $display->content['new-4'] = $pane; + $display->panels['middle'][1] = 'new-4'; + $pane = new stdClass(); + $pane->pid = 'new-5'; + $pane->panel = 'right'; + $pane->type = 'custom'; + $pane->shown = '1'; + $pane->subtype = 'custom'; + $pane->access = array(); + $pane->configuration = array( + 'style' => 'default', + 'override_title' => 0, + 'override_title_text' => '', + 'css_id' => '', + 'css_class' => '', + 'title' => 'Relcontext', + 'body' => 'The relcontext content_type gets its data from a relcontext, which is an example of a relationship. This panel should be run with an argument like "/xxx", which allows the simplecontext to get its context, and then the relcontext is configured in this panel to get (create) its data from the simplecontext.', + 'format' => '1', + ); + $pane->cache = array(); + $display->content['new-5'] = $pane; + $display->panels['right'][0] = 'new-5'; + $pane = new stdClass(); + $pane->pid = 'new-6'; + $pane->panel = 'right'; + $pane->type = 'relcontext_item'; + $pane->shown = '1'; + $pane->subtype = 'description'; + $pane->access = array(); + $pane->configuration = array( + 'context' => 'relationship_relcontext_from_simplecontext_1', + 'style' => 'default', + 'override_title' => 0, + 'override_title_text' => '', + 'css_id' => '', + 'css_class' => '', + 'config_item_1' => 'default1', + ); + $pane->cache = array(); + $display->content['new-6'] = $pane; + $display->panels['right'][1] = 'new-6'; + $pane = new stdClass(); + $pane->pid = 'new-7'; + $pane->panel = 'top'; + $pane->type = 'custom_php'; + $pane->shown = '1'; + $pane->subtype = 'custom_php'; + $pane->access = array(); + $pane->configuration = array( + 'style' => 'default', + 'override_title' => 0, + 'override_title_text' => '', + 'css_id' => '', + 'css_class' => '', + 'title' => '', + 'body' => '$arg = arg(1); + $arg0 = arg(0); + if (!$arg) { + $block->content = <<This page is intended to run with an arg and you don\'t have one. +
+ Without an arg, the page doesn\'t have any context. +
Please try something like "/$arg0/xxx" +END; + + $block->title = "This is intended to run with an argument"; + } else { + $block->content = "The arg for this page is \'$arg\'"; + }', + ); + $pane->cache = array(); + $display->content['new-7'] = $pane; + $display->panels['top'][0] = 'new-7'; + $page->display = $display; + $page->displays = array(); + $pages['ctools_plugin_example'] = $page; + + + return $pages; +} Index: ctools_plugin_example/plugins/access/arg_length.inc =================================================================== --- ctools_plugin_example/plugins/access/arg_length.inc (revision 0) +++ ctools_plugin_example/plugins/access/arg_length.inc (revision 0) @@ -0,0 +1,73 @@ + t("Arg Length"), + 'description' => t('Control access by length of Simplecontext argument.'), + 'callback' => 'ctools_plugin_example_arg_length_ctools_access_check', + 'settings form' => 'ctools_plugin_example_arg_length_ctools_access_settings', + 'summary' => 'ctools_plugin_example_arg_length_ctools_acesss_summary', + 'required context' => new ctools_context_required(t('Simplecontext'), 'simplecontext'), + ); + + return $args; +} + +/** + * Settings form for the 'by role' access plugin + */ +function ctools_plugin_example_arg_length_ctools_access_settings(&$form, &$form_state, $conf) { + $form['settings']['greater_than'] = array( + '#type' => 'radios', + '#title' => t('Grant access if simplecontext argument length is'), + '#options' => array(1 => t('Greater than'), 0 => t('Less than or equal to')), + '#default_value' => $conf['greater_than'], + ); + + $form['settings']['arg_length'] = array( + '#type' => 'textfield', + '#title' => t('Length of Simplecontext argument'), + '#size' => 3, + '#default_value' => $conf['arg_length'], + '#description' => t('Access/Visibility will be granted based on arg length.'), + ); +} + + +/** + * Check for access. + */ +function ctools_plugin_example_arg_length_ctools_access_check($conf, $context) { + // As far as I know there should always be a context at this point, but this + // is safe. + if (empty($context) || empty($context->data)) { + return FALSE; + } + + $compare = ($context->arg_length > $conf['arg_length']); + if ( ($compare && $conf['greater_than']) || (!$compare && !$conf['greater_than'])) { + return TRUE; + } + return FALSE; +} + +/** + * Provide a summary description based upon the checked roles. + */ +function ctools_plugin_example_arg_length_ctools_acesss_summary($conf, $context) { + + return t('Simpletext argument must be !comp @length characters', + array('!comp' => $conf['greater_than'] ? 'greater than' : 'less than or equal to', + '@length' => $conf['arg_length'])); +} + Index: ctools_plugin_example/plugins/access/example_role.inc =================================================================== --- ctools_plugin_example/plugins/access/example_role.inc (revision 0) +++ ctools_plugin_example/plugins/access/example_role.inc (revision 0) @@ -0,0 +1,83 @@ + t("Ctools Example: role"), + 'description' => t('Control access by role.'), + 'callback' => 'ctools_plugin_example_example_role_ctools_access_check', + 'default' => array('rids' => array()), + 'settings form' => 'ctools_plugin_example_example_role_ctools_access_settings', + 'summary' => 'ctools_plugin_example_example_role_ctools_acesss_summary', + 'required context' => new ctools_context_required(t('User'), 'user'), + ); + + return $args; +} + +/** + * Settings form for the 'by role' access plugin + */ +function ctools_plugin_example_example_role_ctools_access_settings(&$form, &$form_state, $conf) { + $form['settings']['rids'] = array( + '#type' => 'checkboxes', + '#title' => t('Role'), + '#default_value' => $conf['rids'], + '#options' => ctools_get_roles(), + '#description' => t('Only the checked roles will be granted access.'), + ); +} + +/** + * Compress the roles allowed to the minimum. + */ +function ctools_plugin_example_example_role_ctools_access_settings_submit(&$form, &$form_state) { + $form_state['values']['settings']['rids'] = array_keys(array_filter($form_state['values']['settings']['rids'])); +} + +/** + * Check for access. + */ +function ctools_plugin_example_example_role_ctools_access_check($conf, $context) { + // As far as I know there should always be a context at this point, but this + // is safe. + if (empty($context) || empty($context->data) || !isset($context->data->roles)) { + return FALSE; + } + + $roles = array_keys($context->data->roles); + $roles[] = $context->data->uid ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID; + return (bool) array_intersect($conf['rids'], $roles); +} + +/** + * Provide a summary description based upon the checked roles. + */ +function ctools_plugin_example_example_role_ctools_acesss_summary($conf, $context) { + if (!isset($conf['rids'])) { + $conf['rids'] = array(); + } + $roles = ctools_get_roles(); + + $names = array(); + foreach (array_filter($conf['rids']) as $rid) { + $names[] = check_plain($roles[$rid]); + } + + if (empty($names)) { + return t('@identifier can have any role', array('@identifier' => $context->identifier)); + } + + return format_plural(count($names), '@identifier must have role "@roles"', '@identifier can be one of "@roles"', array('@roles' => implode(', ', $names), '@identifier' => $context->identifier)); +} + Index: ctools_plugin_example/plugins/arguments/simplecontext_arg.inc =================================================================== --- ctools_plugin_example/plugins/arguments/simplecontext_arg.inc (revision 0) +++ ctools_plugin_example/plugins/arguments/simplecontext_arg.inc (revision 0) @@ -0,0 +1,62 @@ +__ctools_arguments() + * + * @return unknown_type + */ +function ctools_plugin_example_simplecontext_arg_ctools_arguments() { + $args['simplecontext_arg'] = array( + 'title' => t("Simplecontext arg"), + // keyword to use for %substitution + 'keyword' => 'simplecontext', + 'description' => t('Creates a "simplecontext" from the arg.'), + 'context' => 'simplecontext_arg_context', + // 'settings form' => 'simplecontext_arg_settings_form', + + // placeholder_form is used in panels preview, for example, so we can + // preview without getting the arg from a URL + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the simplecontext arg'), + ), + + ); + return $args; +} + +/** + * Get the simplecontext context using the arg. In this case we're just going + * to manufacture the context from the data in the arg, but normally it would + * be an API call, db lookup, etc. + */ +function simplecontext_arg_context($arg = NULL, $conf = NULL, $empty = FALSE) { + // If $empty == TRUE it wants a generic, unfilled context. + if ($empty) { + return ctools_context_create_empty('simplecontext'); + } + + // Do whatever error checking is required, returning FALSE if it fails the test + // Normally you'd check + // for a missing object, one you couldn't create, etc. + if (empty($arg)) { + return FALSE; + } + + return ctools_context_create('simplecontext', $arg); +} Index: ctools_plugin_example/plugins/content_types/icon_example.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: ctools_plugin_example/plugins/content_types/icon_example.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: ctools_plugin_example/plugins/content_types/no_context_content_type.inc =================================================================== --- ctools_plugin_example/plugins/content_types/no_context_content_type.inc (revision 0) +++ ctools_plugin_example/plugins/content_types/no_context_content_type.inc (revision 0) @@ -0,0 +1,121 @@ +__ctools_content_types() + */ +function ctools_plugin_example_no_context_content_type_ctools_content_types() { + // Key must be the name of the content type + $items['no_context_content_type'] = array( + 'title' => t('Ctools Example No Context Content Type'), + 'description' => t('No Context Content Type - requires and uses no context.'), + + // 'single' => TRUE means has no subtypes + 'single' => TRUE, + // Constructor + 'content_types' => array('no_context_content_type'), + // Name of a function which will render the block + 'render callback' => 'no_context_content_type_render', + // The default context + 'defaults' => array(), + + // This explicitly declares the config form. Without this line, the func would be + // ctools_plugin_example_no_context_content_type_edit_form + 'edit form' => 'no_context_content_type_edit_form', + + // goes in the directory with the content type. Here, in panels/content_types + 'icon' => 'icon_example.png', + // 'required context' => new ctools_context_required(t('Junk'), 'junk'), + 'category' => array(t('Ctools Examples'), -9), + + ); + return $items; +} + +/** + * Run-time rendering of the body of the blcok + * + * @param $subtype + * @param $conf Configuration as done at admin time + * @param $args + * @param $context Context - in this case we don't have any + * + * @return unknown_type An object with at least title and content members + */ +function no_context_content_type_render($subtype, $conf, $args, $context) { + $block = new stdClass(); + + $ctools_help = theme('advanced_help_topic', 'ctools', 'plugins', 'title'); + $ctools_plugin_example_help = theme('advanced_help_topic','ctools_plugin_example','Chaos-Tools--Ctools--Plugin-Examples','title'); + + // The title actually used in rendering + $block->title = check_plain("No-context Content Type"); + $block->content = <<Welcome to the Ctools Plugin Example demonstration panel. + + This block is a content type which requires no context at all. It's like a custom block, + but not even that sophisticated. + + For more information on the example plugins, please see the advanced help for + + {$ctools_help} and {$ctools_plugin_example_help} + +END; + if (!empty($conf)) { + $block->content .= '
The only information that can be displayed in this block comes from the code and its settings form:
'; + $block->content .= '
' . var_export($conf, TRUE). '
'; + } + + return $block; + +} + +/** + * 'Edit form' callback for the content type + * This example just returns a form; validation and submission are standard drupal + * Note that if we had not provided an entry for this in hook_content_types, + * this could have had the default name + * ctools_plugin_example_no_context_content_type_edit_form + * + */ +function no_context_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $form['item1'] = array( + '#type' => 'textfield', + '#title' => t('Item1'), + '#size' => 50, + '#description' => t('The setting for item 1.'), + '#default_value' => $conf['item1'], + '#prefix' => '
', + '#suffix' => '
', + ); + $form['item2'] = array( + '#type' => 'textfield', + '#title' => t('Item2'), + '#size' => 50, + '#description' => t('The setting for item 2'), + '#default_value' => $conf['item2'], + '#prefix' => '
', + '#suffix' => '
', + ); + + return $form; +} + +function no_context_content_type_edit_form_submit(&$form, &$form_state) { + foreach (array('item1', 'item2') as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} \ No newline at end of file Index: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc =================================================================== --- ctools_plugin_example/plugins/content_types/relcontext_content_type.inc (revision 0) +++ ctools_plugin_example/plugins/content_types/relcontext_content_type.inc (revision 0) @@ -0,0 +1,121 @@ +__ctools_content_types() + */ +function ctools_plugin_example_relcontext_content_type_ctools_content_types() { + // Key must be the name of the content type + $items['relcontext_content_type'] = array( + // Unknown where this is used + 'title' => t('Ctools Example Relcontext Content Type'), + // 'admin title' => 'ctools_plugin_example_relcontext_content_type_admin_title', + 'admin info' => 'ctools_plugin_example_relcontext_content_type_admin_info', + // Constructor? + 'content_types' => 'relcontext_content_type', + 'single' => TRUE, + 'render callback' => 'relcontext_content_type_render', + // goes in the directory with the content type. Here, in panels/content_types + 'icon' => 'icon_example.png', + 'description' => t('Relcontext content type - works with relcontext context.'), + 'required context' => new ctools_context_required(t('Relcontext'), 'relcontext'), + 'category' => array(t('Ctools Examples'), -9), + 'edit form' => 'relcontext_edit_form', + + ); + return $items; +} + + +//function ctools_plugin_example_relcontext_content_type_admin_title($subtype, $conf) { +// $output = t('Custom'); +// if (!empty($conf['title'])) { +// $output .= " (" . filter_xss_admin($conf['title']) . ")"; +// } +// return $output; +//} + + +/** + * Run-time rendering of the body of the blcok + * + * @param $subtype + * @param $conf Configuration as done at admin time + * @param $args + * @param $context Context - in this case we don't have any + * + * @return unknown_type An object with at least title and content members + */ +function relcontext_content_type_render($subtype, $conf, $args, $context) { + $data = $context->data; + $block = new stdClass(); + + // Don't forget to check this data if it's untrusted + // The title actually used in rendering + $block->title = "Relcontext content type"; + $block->content = << + In our case, the configuration form (\$conf) has just one field, 'config_item_1; + and it's configured with: +END; + if (!empty($conf)) { + $block->content .= '
' . var_export($conf['config_item_1'], TRUE) . '
'; + } + if (!empty($context)) { + $block->content .= '
The args ($args) were
' . + var_export($args, TRUE). '
'; + } + $block->content .= '
And the relcontext context ($context->data->description) , + (which was created from a + simplecontext context) was
' . + print_r($context->data->description,TRUE) . '
'; + + return $block; + +} + + +/** + * 'Edit' callback for the content type + * This example just returns a form + * + */ +function relcontext_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $form['config_item_1'] = array( + '#type' => 'textfield', + '#title' => t('Config Item 1 (relcontext)'), + '#size' => 50, + '#description' => t('Setting for relcontext.'), + '#default_value' => $conf['config_item_1'], + '#prefix' => '
', + '#suffix' => '
', + ); + + return $form; +} + +function relcontext_edit_form_submit(&$form, &$form_state) { + foreach (array_keys($form) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} Index: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc =================================================================== --- ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc (revision 0) +++ ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc (revision 0) @@ -0,0 +1,134 @@ +__ctools_content_types() + */ +function ctools_plugin_example_simplecontext_content_type_ctools_content_types() { + // Key must be the name of the content type + $items['simplecontext_content_type'] = array( + 'title' => t('Simplecontext Content Type'), + // Constructor? + 'content_types' => 'simplecontext_content_type', + // 'single' means not to be subtyped + 'single' => TRUE, + // Name of a function which will render the block + 'render callback' => 'simplecontext_content_type_render', + + // goes in the directory with the content type. Here, in panels/content_types + 'icon' => 'icon_example.png', + 'description' => t('Simplecontext content type - works with a simplecontext context.'), + 'required context' => new ctools_context_required(t('Simplecontext'), 'simplecontext'), + 'edit form' => 'simplecontext_content_type_edit_form', + 'admin title' => 'ctools_plugin_example_simplecontext_content_type_admin_title', + 'admin info' => 'ctools_plugin_example_simplecontext_content_type_admin_info', + 'category' => array(t('Ctools Examples'), -9), + + ); + return $items; +} + +function ctools_plugin_example_simplecontext_content_type_admin_title($subtype, $conf, $context = NULL) { + $output = t('Simplecontext'); + if ($conf['override_title'] && !empty($conf['override_title_text'])) { + $output = filter_xss_admin($conf['override_title_text']); + } + return $output; +} + + + +/** + * Callback to provide administrative info. In this case we'll render the + * content as long as it's not PHP, which is too risky to render here. + */ +function ctools_plugin_example_simplecontext_content_type_admin_info($subtype, $conf, $context = NULL) { + $block = new stdClass(); + $block->title = check_plain($conf['title']); + if (!empty($context) && !empty($context->data->description)) { + $block->content = check_plain($context->data->description); + } + return $block; + +} + +/** + * Run-time rendering of the body of the block (content type) + * + * @param $subtype + * @param $conf Configuration as done at admin time + * @param $args + * @param $context Context - in this case we don't have any + * + * @return unknown_type An object with at least title and content members + */ +function simplecontext_content_type_render($subtype, $conf, $args, $context) { + $data = $context->data; + $block = new stdClass(); + + // Don't forget to check this data if it's untrusted + // The title actually used in rendering + $block->title = "Simplecontext Content Type"; + $block->content = << + In our case, the configuration form (\$conf) has just one field, 'config_item_1; + and it's configured with: +END; + if (!empty($conf)) { + $block->content .= '
' . print_r($conf['config_item_1'], TRUE) . '
'; + } + if (!empty($context)) { + $block->content .= '
The args ($args) were
' . + var_export($args, TRUE). '
'; + } + $block->content .= '
And the simplecontext context ($context->data->description) was
' . + print_r($context->data->description,TRUE) . '
'; + + return $block; +} + + +/** + * 'Edit' callback for the content type + * This example just returns a form + * + */ +function simplecontext_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $form['config_item_1'] = array( + '#type' => 'textfield', + '#title' => t('Config Item 1 for simplecontext content type'), + '#size' => 50, + '#description' => t('The stuff for item 1.'), + '#default_value' => $conf['config_item_1'], + '#prefix' => '
', + '#suffix' => '
', + ); + + return $form; +} + +function simplecontext_content_type_edit_form_submit(&$form, &$form_state) { + foreach (array_keys($form) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + Index: ctools_plugin_example/plugins/contexts/relcontext.inc =================================================================== --- ctools_plugin_example/plugins/contexts/relcontext.inc (revision 0) +++ ctools_plugin_example/plugins/contexts/relcontext.inc (revision 0) @@ -0,0 +1,86 @@ + t("relcontext"), + 'description' => t('A relcontext object.'), + // Function to create the relcontext + 'context' => 'ctools_plugin_example_context_create_relcontext', + // Function that does the settings + 'settings form' => 'relcontext_settings_form', + 'keyword' => 'relcontext', + 'context name' => 'relcontext', + ); + return $args; +} + +/** + * Create a context, either from manual configuration or from an argument on the URL + * + * @param $empty If true, just return an empty context + * @param $data If from settings form, an array as from a form. If from argument, a string + * @param $conf TRUE if the $data is coming from admin configuration, FALSE if it's from a URL arg + * + * @return a Context object + */ +function ctools_plugin_example_context_create_relcontext($empty, $data = NULL, $conf = FALSE) { + $context = new ctools_context('relcontext'); + $context->plugin = 'relcontext'; + + if ($empty) { + return $context; + } + + if ($conf) { + if (!empty($data)) { + $context->data = new stdClass(); + + // For this simple item we'll just create our data by stripping non-alpha and + // adding 'sample_relcontext_setting' to it + $context->data->description = 'relcontext_from__' . preg_replace('/[^a-z]/i','',$data['sample_relcontext_setting']); + $context->data->description .= '_from_configuration_sample_simplecontext_setting'; + $context->title = t("Relcontext Context from Simplecontext"); + return $context; + + } + } + else { + // $data is coming from an arg - it's just a string + // This is used for keyword + $context->title = "relcontext_" . $data->data->description; + $context->argument = $data->argument; + // Make up a bogus context + $context->data = new stdClass(); + // For this simple item we'll just create our data by stripping non-alpha and + // prepend 'relcontext_' and + // adding '_created_from_from_simplecontext' to it + $context->data->description = 'relcontext_' . preg_replace('/[^a-z]/i','',$data->data->description); + $context->data->description .= '_created_from_simplecontext'; + + return $context; + } +} + +function relcontext_settings_form($conf, $external = FALSE) { + $form = array(); + $form['sample_relcontext_setting'] = array( + '#type' => 'textfield', + '#title' => t('Relcontext setting'), + '#size' => 50, + '#description' => t('Just an example setting.'), + '#default_value' => $conf['default relcontext setting'], + '#prefix' => '
', + '#suffix' => '
', + ); + return $form; +} + Index: ctools_plugin_example/plugins/contexts/simplecontext.inc =================================================================== --- ctools_plugin_example/plugins/contexts/simplecontext.inc (revision 0) +++ ctools_plugin_example/plugins/contexts/simplecontext.inc (revision 0) @@ -0,0 +1,96 @@ + t("Simplecontext"), + 'description' => t('A single "simplecontext" context, or data element.'), + 'context' => 'ctools_plugin_example_context_create_simplecontext', // func to create context + 'context name' => 'simplecontext', + 'settings form' => 'simplecontext_settings_form', + 'keyword' => 'simplecontext', + 'context name' => 'simplecontext', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter some data to represent this "simplecontext".'), + ), + + ); + return $args; +} + +/** + * Create a context, either from manual configuration or from an argument on the URL + * + * @param $empty If true, just return an empty context + * @param $data If from settings form, an array as from a form. If from argument, a string + * @param $conf TRUE if the $data is coming from admin configuration, FALSE if it's from a URL arg + * + * @return a Context object + */ +function ctools_plugin_example_context_create_simplecontext($empty, $data = NULL, $conf = FALSE) { + $context = new ctools_context('simplecontext'); + $context->plugin = 'simplecontext'; + + if ($empty) { + return $context; + } + + if ($conf) { + if (!empty($data)) { + $context->data = new stdClass(); + + // For this simple item we'll just create our data by stripping non-alpha and + // adding '_from_configuration_item_1' to it + $context->data->description = preg_replace('/[^a-z]/i','',$data['sample_simplecontext_setting']); + $context->data->description .= '_from_configuration_sample_simplecontext_setting'; + $context->title = t("Simplecontext Context from config"); + return $context; + } + } + else { + // $data is coming from an arg - it's just a string + // This is used for keyword + $context->title = $data; + $context->argument = $data; + // Make up a bogus context + $context->data = new stdClass(); + // For this simple item we'll just create our data by stripping non-alpha and + // adding '_from_simplecontext_argument' to it + $context->data->description = preg_replace('/[^a-z]/i','',$data); + $context->data->description .= '_from_simplecontext_argument'; + $context->arg_length = strlen($context->argument); + +// $context->data->description = "
+// Data: >{" . print_r($data,TRUE) . "}< +// This context was created from an argument.
"; + return $context; + } +} + +function simplecontext_settings_form($conf, $external = FALSE) { + if (empty($conf)) { + $conf = array( + 'sample_simplecontext_setting' => 'default simplecontext setting', + ); + } + + $form = array(); + $form['sample_simplecontext_setting'] = array( + '#type' => 'textfield', + '#title' => t('Setting for simplecontext'), + '#size' => 50, + '#description' => t('An example setting that could be used to configure a context'), + '#default_value' => $conf['sample_simplecontext_setting'], + '#prefix' => '
', + '#suffix' => '
', + ); + return $form; +} + Index: ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc =================================================================== --- ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc (revision 0) +++ ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc (revision 0) @@ -0,0 +1,52 @@ + t("Relcontext from Simplecontext"), + 'keyword' => 'relcontext', + 'description' => t('Adds a relcontext from existing simplecontext.'), + 'required context' => new ctools_context_required(t('Simplecontext'), 'simplecontext'), + 'context' => 'ctools_relcontext_from_simplecontext_context', + 'settings form' => 'ctools_relcontext_from_simplecontext_settings_form', + ); + return $args; +} + +/** + * Return a new context based on an existing context + */ +function ctools_relcontext_from_simplecontext_context($context = NULL, $conf) { + // If unset it wants a generic, unfilled context, which is just NULL + if (empty($context->data)) { + return ctools_context_create_empty('relcontext', NULL); + } + + // You should do error-checking here + + // Create the new context from some element of the parent context. + // In this case, we'll pass in the whole context so it can be used to + // create the relcontext + return ctools_context_create('relcontext',$context); + +} + +/** + * Settings form for the relationship + */ +function ctools_relcontext_from_simplecontext_settings_form($conf) { + // We won't configure it in this case + + return array(); +} +