CTools/export collects default information via a meta hook called hook_ctools_plugin_api(). For instance, this is how such a hook implementation looks like for default hook hook_data_default():

/**
 * Implementation of hook_ctools_plugin_api().
 */
function tic_ctools_plugin_api($module, $api) {
  if ($module == 'data' && $api == 'data_default') {
    return array(
      'version' => 1,
      'file' => 'tic.features.inc',
      'path' => drupal_get_path('module', 'tic'),
    );
  }
}

I'm planning on submitting a patch. Expect me poking you off-site for some guidance on this issue :-)

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

alex_b’s picture

Assigned: alex_b » Unassigned
Status: Active » Needs review
FileSize
5.9 KB

Here we go: first round with the help of mr miccolis.

Tested only on my local environment with data module.

1) Question: ctools_features_api() does not define a default hook. Could there be a problem with that? I didn't find this hook to do anything and ctools exposes a dynamic number of default hooks via schema info of configuration tables and hook_ctools_plugin_api().

2) To be tested: ctools_features_export() delegates hook_features_export() to ctools API users that also implement a hook_features_export(). This should allow ctools/features users to define complex dependencies by passing on the pipe ;-) jeff pointed me to using _features_populate() which is a great idea - untested yet.

3) Interesting: The fact that hook_features_export_render() can return any number of exportables keyed by hook name is terrific. Thus I could integrate ctools particular setup that requires a hook_ctools_plugin_api() implementation (think views) that declares the default hooks and further the actual implementation of these default hooks.

4) To be discussed: Unfortunately, hook_ctools_plugin_api() expects two parameters $module and $api. I had to patch features_export_render_features() and create a variable pass through. This is not exactly pretty, but it works transparently to the existing API.

[edit]

5) Features API does not expect that a module like CTools would expose default hooks on behalf of other modules. I've solved this problem by encoding module/table information into the features string delimited by slashes / - this is not pretty and we should think about a better solution. However, it works for now and is transparent to the existing API.

alex_b’s picture

Of course, when we export with ctools, we will require ctools. Need to add ctools to the dependency array in ctools_features_export():

$export['dependencies']['ctools'] = 'ctools';

Leaving this on review to get maintainers to look at the overall approach.

alex_b’s picture

Fixes #2

alex_b’s picture

This patch changes the weird 'module / table / key' convention to a slightly less weird 'module.table.key' format - so that your .info files don't read anymore:

features[ctools][] = "module / table / key" 

but

features[ctools][] = "module.table.key"
alex_b’s picture

Fixes a problem where the $export array in default hooks wasn't properly keyed and exportables overwrote each other.

yhahn’s picture

I've done some significant refactoring of this patch to make use of fago's work that allows for a single module to provide multiple components. One limitation of the current API is that it assumes the component namespace is the same as the hook namespace -- e.g. if your components are "panels", it expects to call "panels_features_export", etc.

After considering whether the API should be made more complex to accommodate CTools' particularly unusual case, I decided to try a different tactic -- the ctools include now declares functions dynamically (thank you eval()) in each of the namespaces of its components. Other than this rather egregious hack, the code becomes much easier to read and understand as it much more closely mirrors the implementations of other modules.

An additional benefit to this is that ctools-provided components are split up by their storage types rather than being clumped together under ctools:

features[ctools][] = "data_tables"
features[data_tables][] = "data_table_news_feed"

Under this model, hook_ctools_plugins_api is itself the defaults hook for the ctools component which lists the different implementing modules that this feature meets API compatibility with.

jmiccolis’s picture

Status: Needs review » Closed (fixed)

Nice job guys. Comitted.

floretan’s picture

Status: Closed (fixed) » Reviewed & tested by the community

It looks like features.ctools.inc didn't get committed with the rest of the patch.

jmiccolis’s picture

Status: Reviewed & tested by the community » Fixed

You are indeed correct. It *should* be there now.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

ceardach’s picture

Status: Closed (fixed) » Needs work
FileSize
929 bytes
1.92 KB

I've tried to use this, and it isn't working.

I created a simple panel page, one column that has custom content and a menu item attached to the features menu. I then export this panel page as a feature. Wiping the database, and enabling the feature doesn't work.

The code creating the panels hook is incorrect, and incomplete. It is referencing hook_()

I have attached an export of the feature, and the panel page as it should have been.

ceardach’s picture

I am unable to create a patch for features to fix this. But here's what I can do manually in order to get a panel as part of a feature.

I deleted the MODULE_NAME_() and _MODULE_NAME_() functions since they weren't doing anything. In _MODULE_NAME_ctools_plugin_api() I changed it from this:

function _test_ctools_plugin_api() {
  $args = func_get_args();
  $module = array_shift($args);
  $api = array_shift($args);
  if ($module == "page_manager" && $api == "default_page_manager_handlers") {
    return array("version" => 1);
  }
  else if ($module == "page_manager" && $api == "default_page_manager_pages") {
    return array("version" => 1);
  }
}

to this:

function _test_ctools_plugin_api() {
  $args = func_get_args();
  $module = array_shift($args);
  $api = array_shift($args);
  if ($module == 'page_manager' && $api == 'pages_default') {
    return array('version' => 1);
  }
}

I then created a MODULE_NAME.pages_default.inc file and inside placed the following:

function test_default_page_manager_pages() {
  // my exported panel code
  $pages['PAGE_NAME'] = $page;
  return $pages;
floretan’s picture

Status: Needs work » Needs review
FileSize
1.11 KB

The ctools implementation of hook_features_export_render() must use ctools_export_get_schema() in order to get the 'default hook' option. This missing default hook caused the functions called hook_()

Also, ctools_export_load_object() was set to only return names. We need to return an array of objects, we already have the names of the ones we need.

With this patch, the features module generates implementations of default hooks that are recognized by ctools (tried with panels). However, this export doesn't have all the data. For example, when exporting a panel, you only get the top-level components like pages and handlers, but not their child components like panes and displays.

yhahn’s picture

Status: Needs review » Fixed

Awesome, thank you. Committed: http://drupal.org/project/cvs/401392

Let's make a new issue regarding full panels exporting -- because panels stores its components across multiple tables, it will likely need a custom implementation beyond the generic ctools-features integration to get the panel and the child components.

dmitrig01’s picture

No, it doesn't need a custom implementation. What's wrong with panels is that the ctools integration is fundamentally flawed. It should use ctools' bulk export mechanism, which works properly for panels as well as everything else. the Bulk Export module is basically just a frontend to the backend which features should use.

dmitrig01’s picture

http://pastie.textmate.org/private/yucgpeytnyyathxvei9m4g is an initial attempt at the code for bulk export

jmiccolis’s picture

@dmitrig01 when you get closer to a patch that we can commit please post it on a fresh issue? thx!

floretan’s picture

I believe the current ctools export is actually incomplete, so I'm staying in this issue for now.

Here's a patch derived from @dmitrig01's pastebin. The main difference is a fix for the parameters of hook_ctools_plugin_api() (the hook takes $api instead of $default_hook). CTools objects used to get exported and features could update/revert them, but the defaults didn't get recognized by CTools.

floretan’s picture

Category: feature » bug
Status: Fixed » Needs review
floretan’s picture

Apparently the patch didn't get attached...

dmitrig01’s picture

btw, the only reason this:

+  if (function_exists('page_manager_page_manager_handlers_list')) {
+    page_manager_page_manager_handlers_list();

exists is so panels works. Sorry but a necesarry hack.

JacobSingh’s picture

Patch in #20 worked for me while exporting a decently complicated panel, but didn't do a review of the code itself.

JacobSingh’s picture

Title: CTools/export integration » CTools/export integration - Including Panels export

Sorry, just changing the title to make this easier for people to find.

floretan’s picture

I have also used this patch on two different projects, with different kinds of panels including mini-panels, and it's worked without any problems.

JacobSingh’s picture

Okay, I'm not sure if this is a bug in this patch, or just something that hasn't been written yet and should be in a different issue, but when exporting pages, it is not finding the fact that I'm using views and exporting those views as dependencies.

jmiccolis’s picture

Attached is a version of the patch that is slightly more robust - it works with modules that don't explicitly implement a 'list callback' or 'export callback'.

I've tested with it with basic panels, but would appreciate testing from those of you who have more complex ones.

@jacobsingh, the auto detection of depending components (ie, the views your panel contains) is not magic, and must be written. Take a look at views_features_export() in features/includes/features.views.inc to see how it's done for views.

redben’s picture

Awesome !
Any chances this last patch gets reviewed soon ?

m.stenta’s picture

(subscribing)

frankcarey’s picture

Status: Needs review » Reviewed & tested by the community

working well for me now :)

SocialNicheGuru’s picture

does this mean that panels now works with Features and spaces?

when I enabled user/%user override in panels, spaces redirect was overwritten.

Will this patch solve that problem?

Thanks,
Chris

frankcarey’s picture

not 100% since i haven't read the code, but it think this will only allow you to import and export panels, now that bulk export functionality exists in ctools. Regarding your issue, maybe you can change the module weight of space so that it is the last to override? Maybe the spaces issue queue would be a helpful place.

randallknutson’s picture

Been testing out patch in #26.

Seems to work well with importing and exporting panels. The only issue I've run into is that once a feature is created, a change to the panel page won't mark the feature as "Overridden." I can force the feature to update using "drush features update FEATURENAME" but when I move it to a new system and revert, it says "Current state already matches defaults, aborting." When I look at the code for my exported panel, the change is there.

Seems that the diff function is not correctly seeing that panels have changed.

randallknutson’s picture

Figured out why panels wasn't being recognized as changed. function features_var_export had the wrong recursive call if the $var is an object.

Patch attached.

jmiccolis’s picture

Status: Reviewed & tested by the community » Needs review

@lladnar1, thanks for giving it a solid run through.

Setting this back to 'needs review' as I'd love to get a confirmation of the fix in#33 plus we should to assemble a patch that combines #26 & #33. I'll certainly post and update if I get the time to look this over.

SocialNicheGuru’s picture

#33, what release was this against. I don't find these lines in the specified file.

randallknutson’s picture

@SocialNicheGuru

I'm on the latest dev version (Oct 17 I believe)

It is in the file:
features/features.export.inc (Line 443)

I've also since discovered that you can't revert a panel page using "drush features revert XXX". Not the end of the world but it would be nice.

dmitrig01’s picture

Status: Needs review » Reviewed & tested by the community

Just exported a panel (needs both patches) and it worked awesomely!

dmitrig01’s picture

Status: Reviewed & tested by the community » Needs work

I take it back - i'm getting fatal errors when trying to revert

dmitrig01’s picture

I re-take-that-back - it does work

himerus’s picture

I know it's been mentioned to start a new thread, but this one still seems like it's moving along.

@dmitrig01 with your "success", did that include both the panel/handler structure, and the content?

I attempted for the first time today a features export with Panels, and had everything "perfect", the only thing that is/was missing in the feature export was the layout & content data for the panel.

Without digging into the code at this point, I only saw that 2 items gave "issue" in the feature selection process, which was the panels_display and panels_pane, both of which only show a single checkbox with no associated data.

So in sort, did applying both the patches mentioned above (#26 & #33) fix this issue for you & allow you to export ALL the appropriate data to recreate your panels in a new environment?

himerus’s picture

I can verify now after some testing that using the two patches mentioned in my previous comment DO in fact fix the issue with properly exporting the panel layout & content data.

I need to do some more playing around, as there seemed to be issues with the style settings for the panes (skinr) not being saved properly upon a fresh import of the feature, and issues with the CCK field(s) in the feature being marked "needs review" after a fresh import. Not sure if this was the case prior to patching or not.

However, it does appear that applying the 2 patches above properly gives me the panel layout information & pane data that was missing from prior exports.

dmitrig01’s picture

yeah, i was experiencing an unrelated problem

DamienMcKenna’s picture

Thanks for the fix, guys, was wondering why it wasn't working properly.

dixon_’s picture

Status: Needs work » Reviewed & tested by the community

The patch in #33 seems to be committed already. And by applying the patch from #26 I can export panels with my features!

I think the patch in #26 is ready to be committed. Every one that has tested it seems to have done that successfully, including me.

rlnorthcutt’s picture

subscribing

DamienMcKenna’s picture

With the two patches, I'm having trouble reverting features in certain cases. In each case the items which show being overwritten are PAGE_MANAGER_HANDLERS and PAGE_MANAGER_PAGES while other items have been reverted without issue. I don't know if the issue is directly related to these patches. Has anyone else tried reverting changes?

tayzlor’s picture

subscribing

mrfelton’s picture

I can confirm that applying patch at #26 to the latest CVS seems to result in fully functional exports/imports of panels. Haven't don't extensive testing though.

jmiccolis’s picture

Status: Reviewed & tested by the community » Fixed

Patch in #26 has been committed, thanks to everyone who helped testing.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

mbria’s picture

Sorry for this panels/context/spaces newbie question.

We tried the CVS 6.1-dev version of features that we suppose include the mention patches.

We happily found that we could export panels as a feature, so this is what we did successfully.

After this, we tried to include the new feature in a space building a new context.

The point is that the new feature is not shown in context so we don't know how to encapsulate the new panel-feature to be usable in (group, site or user) spaces.

Any clue about how to do this? did we misunderstood something?

Thanks a lot in advance.

drecute’s picture

subscribing

randallknutson’s picture

mbria,

This sounds like a completely separate issue from the original post. If you want an answer, I'd recommend creating a new issue.

This issue is resolved and closed and so unless there is a regression it won't be reopened.