This module is really awesome. I wanted to put forth the idea to make the Admin Views views exportable via features.

If the module is supposed to already support export via Features, then this is what I am getting (and should be retagged as a bug, or PEBCAC!).

If I attempt to add the view into a feature via UI, it shows that it is added by dependency and also adds in the dependency on admin_views, which is correct. However, saving the Feature at this point, the view does not get added, just the dependency.

The same thing happens if I run via drush: drush fe my_module views_view:admin_views_comment
The feedback from drush is that the export was successful, but like the UI export, it does not have the views file.

Thanks

Comments

damiankloip’s picture

The feedback from drush is that the export was successful, but like the UI export, it does not have the views file.

This module only provides default views, so this works no differently to any other view export. So this is equivalent to you creating a feature with view_x in, then creating another feature with view_x in....

I think the problem you are facing is that you are trying to re export the default views provided by admin views into a feature, which is exactly the same as bulk export etc...

So essentially you just have 2 view with the same machine names in code - So which ever module is called last will get the code export in the listing.

So basically, your problem is here, in features.ctools.inc

      // If this object is provided as a default by a different module, don't
      // export and add that module as a dependency instead.
      if (!empty($object->export_module) && $object->export_module !== $module_name) {
damiankloip’s picture

Status: Active » Closed (works as designed)
bkonetzny’s picture

So, it's impossible to export a modified view which has a default in code? How would one provide a modified version of the users admin_view via features? Will duplicating the view with a different machine-name work?

dazz’s picture

You can create a clone of the default view, give it another name/machine-name and make the changes in the new view.
Just disable the default view to avoid conflicts.

You can add your custom view to a feature, don't forget to add the admin_views module as a dependency or your view won't work. It needs the admin_views for the System display plugin.

It would be nice addition to the module to be able to only enable the System display plugin so you can create your custom views.

damiankloip’s picture

We could potentially have a setting to disable all default views... I have been contemplating the idea of that for a while OR... Just splitting the views plugins from the default views into 2 separate modules.

attiks’s picture

#4 is right, clone the view and disable the original one. You can disable it using an install hook like this

/**
 * Implements hook_install().
 */
function MY_FEATURE_install() {
  $status = variable_get('views_defaults', array());
  $status['admin_views_node'] = TRUE;
  variable_set('views_defaults', $status);
}
himynameisseb’s picture

You can use the following hook to update an admin view in code. HOOK_views_default_views_alter().

Your hook will override the admin view. Here are the steps I used to create my admin view:

1. Create a new module
2. Add the hook to the module

function MODULE_views_default_views_alter(&$views) {
}

3. Update the admin view via the views page
4. Save the updated view
5. Click 'export view' (from the selection arrow at the top right of the view).
6. Copy ALL display settings for the view display from the export array EXCEPT the line that creates the display. Example below

/* Display: Defaults */
$handler = $view->new_display('default', 'Defaults', 'default'); // <-- DO NOT COPY THIS
// COPY FROM HERE
$handler->display->display_options['title'] = 'Content';
$handler->display->display_options['css_class'] = 'admin-views-view';
$handler->display->display_options['use_ajax'] = TRUE;
$handler->display->display_options['use_more_always'] = FALSE;
// ETC... TO THE BOTTOM OF THAT DISPLAY ...

7. Get display handler data ready to update. (Included in below example)
8. Add this to you hook
9. Wrap your hook in a check for that display (to stop any errors if the display does not exist). Example of hook is below
10. Repeat for all displays.

function MODULE_views_default_views_alter(&$views) {

  // Update the default display
  if(!empty($views['admin_views_node']->display['default']->handler)) {
    // Set handler for default display
    $handler = $views['admin_views_node']->display['default']->handler;
    
    // copy the default display array here... eg.
    $handler->display->display_options['title'] = 'Content';
    $handler->display->display_options['css_class'] = 'admin-views-view';
    $handler->display->display_options['use_ajax'] = TRUE;
    // etc...

  }

  // Update the system_1 display
  if(!empty($views['admin_views_node']->display['system_1']->handler)) {

    // Set handler
    $handler = $views['admin_views_node']->display['system_1']->handler;

    // copy the system_1 display array here... eg.
    $handler->display->display_options['title'] = 'Content';
    $handler->display->display_options['css_class'] = 'admin-views-view';
    $handler->display->display_options['use_ajax'] = TRUE;
    // etc...
  }
}

I hope this helps someone.

david.czinege’s picture

Issue summary: View changes

Thank you sebanthony. Your code above is working for me.

I added one more row to the code, because when i added new fields to the views, and i rearraged them, the alter hook put the fields at the end of the fields list.

I wrote this row:
$handler->display->display_options = array();

after this:
$handler = $views['admin_views_node']->display['default']->handler;

leewoodman’s picture

#4 worked for me and i included the update hook from #6...

Steff1985’s picture

#4 Worked for me.

Thank you !

amfranco’s picture

Before install admin_views you can edit the files in admin_views_default folder, only changing one line: $view->disabled = FALSE; to $view->disabled = TRUE;
Then, install admin_views, clon the view and now you can export the view using features (remember, add the admin_views module as a dependency).

juampynr’s picture

This worked for me and seems to be solid. Please correct me if I am wrong:

1. Disable admin views (user, nodes and files) through the web interface.
2. Clone them (the clones will be active by default).
3. Make all the adjustments that you need to these views.
4. Export these views to code with Features module.
5. Implement the following hook in the .module file of the module where you exported the cloned views:

/**
 * Implememnts hook_views_default_views_alter().
 */
function mymodule_views_default_views_alter(&$views) {
  // Wipe out admin_views as we are overriding them with cloned ones
  // which have been exported into this module through Features.
  $views_to_disable = array('admin_views_file', 'admin_views_node', 'admin_views_user');
  foreach ($views_to_disable as $view) {
    if (isset($views[$view])) {
      unset($views[$view]);
    }
  }
}

6. When you push or pull this code to another environment, make sure that you do drush updatedb && drush fra --yes && drush cc all.

ladybug_3777’s picture

juampynr - I assume you intended for this hook to be added to my exported feature .module file and not added to a different custom module?

/**
 * Implemments hook_views_default_views_alter().
 */
function myfeaturename_views_default_views_alter(&$views) {
  // Wipe out admin_views as we are overriding them with cloned ones
  // which have been exported into this module through Features.
  $views_to_disable = array('admin_views_file', 'admin_views_node', 'admin_views_user');
  foreach ($views_to_disable as $view) {
    if (isset($views[$view])) {
      unset($views[$view]);
    }
  }
}

When I did that the view was not disabled automatically on the other environment, even after running the drush commands. In fact I encountered some strange user errors after enabling the feature.

For now I'm going to have to manually disable the view on the environment I'm moving to.

I'd love to see what was talked about in comment #5 be added as a new option. I think that would make the most sense and would be easier to use.

mrpauldriver’s picture

Agree with #13. It would good if there was an option to export modified views via features.

marcoka’s picture

#7 works perfect. thank you for this detailed instruction.

markie’s picture

So I tried #7 so I could add some filters. Alas, when I view /admin/content it still shows the default. Any ideas? I have tried clearing cache multiple times. (my function is not really called MYMODULE.. that's just to keep the client happy)

/**
 * Implements hook_views_default_views_alter().
 */
function MYMODULE_views_default_views_alter(&$views) {
  // Update Admin Views that can not be exported to a feature.
  if (!empty($views['admin_views_node']->display['default']->handler)) {
    // Set handler for default display.
    $handler = $views['admin_views_node']->display['default']->handler;
    /* Filter criterion: Taxonomy term: Vocabulary */
    // We don't want this item.
    unset($handler->display->display_options['filters']['vid']);
    /* Filter criterion: Taxonomy term: Term */
    $handler->display->display_options['filters']['tid_1']['id'] = 'tid_1';
    $handler->display->display_options['filters']['tid_1']['table'] = 'taxonomy_term_data';
    $handler->display->display_options['filters']['tid_1']['field'] = 'tid';
    $handler->display->display_options['filters']['tid_1']['relationship'] = 'term_node_tid';
    $handler->display->display_options['filters']['tid_1']['value'] = '';
    $handler->display->display_options['filters']['tid_1']['group'] = 1;
    $handler->display->display_options['filters']['tid_1']['exposed'] = TRUE;
    $handler->display->display_options['filters']['tid_1']['expose']['operator_id'] = 'tid_1_op';
    $handler->display->display_options['filters']['tid_1']['expose']['label'] = 'Profession';
    $handler->display->display_options['filters']['tid_1']['expose']['operator'] = 'tid_1_op';
    $handler->display->display_options['filters']['tid_1']['expose']['identifier'] = 'tid_1';
    $handler->display->display_options['filters']['tid_1']['expose']['remember_roles'] = array(
      2 => '2',
      1 => 0,
      30037204 => 0,
      174673798 => 0,
      14522484 => 0,
      233954291 => 0,
      130635651 => 0,
      185712324 => 0,
      254633039 => 0,
      57796051 => 0,
      593464 => 0,
      93255533 => 0,
    );
    $handler->display->display_options['filters']['tid_1']['vocabulary'] = 'profession';
    /* Filter criterion: Taxonomy term: Term */
    $handler->display->display_options['filters']['tid_2']['id'] = 'tid_2';
    $handler->display->display_options['filters']['tid_2']['table'] = 'taxonomy_term_data';
    $handler->display->display_options['filters']['tid_2']['field'] = 'tid';
    $handler->display->display_options['filters']['tid_2']['relationship'] = 'term_node_tid';
    $handler->display->display_options['filters']['tid_2']['value'] = '';
    $handler->display->display_options['filters']['tid_2']['group'] = 1;
    $handler->display->display_options['filters']['tid_2']['exposed'] = TRUE;
    $handler->display->display_options['filters']['tid_2']['expose']['operator_id'] = 'tid_2_op';
    $handler->display->display_options['filters']['tid_2']['expose']['label'] = 'Specialty';
    $handler->display->display_options['filters']['tid_2']['expose']['operator'] = 'tid_2_op';
    $handler->display->display_options['filters']['tid_2']['expose']['identifier'] = 'tid_2';
    $handler->display->display_options['filters']['tid_2']['expose']['remember_roles'] = array(
      2 => '2',
      1 => 0,
      30037204 => 0,
      174673798 => 0,
      14522484 => 0,
      233954291 => 0,
      130635651 => 0,
      185712324 => 0,
      254633039 => 0,
      57796051 => 0,
      593464 => 0,
      93255533 => 0,
    );
    $handler->display->display_options['filters']['tid_2']['vocabulary'] = 'specialty';
    /* Filter criterion: Taxonomy term: Term */
    $handler->display->display_options['filters']['tid']['id'] = 'tid';
    $handler->display->display_options['filters']['tid']['table'] = 'taxonomy_term_data';
    $handler->display->display_options['filters']['tid']['field'] = 'tid';
    $handler->display->display_options['filters']['tid']['relationship'] = 'term_node_tid';
    $handler->display->display_options['filters']['tid']['value'] = '';
    $handler->display->display_options['filters']['tid']['group'] = 1;
    $handler->display->display_options['filters']['tid']['exposed'] = TRUE;
    $handler->display->display_options['filters']['tid']['expose']['operator_id'] = 'tid_op';
    $handler->display->display_options['filters']['tid']['expose']['label'] = 'Learning Category';
    $handler->display->display_options['filters']['tid']['expose']['operator'] = 'tid_op';
    $handler->display->display_options['filters']['tid']['expose']['identifier'] = 'tid';
    $handler->display->display_options['filters']['tid']['expose']['remember_roles'] = array(
      2 => '2',
      1 => 0,
      30037204 => 0,
      174673798 => 0,
      14522484 => 0,
      233954291 => 0,
      130635651 => 0,
      185712324 => 0,
      254633039 => 0,
      57796051 => 0,
      593464 => 0,
      93255533 => 0,
    );
    $handler->display->display_options['filters']['tid']['vocabulary'] = 'learning_category';
  }
}

michaellenahan’s picture

@markie I had a similar same problem to your one. My hook_views_default_views_alter() function was not being called.

In my case, I think it was to do with the module name.

At first I had: zs_admin_views as the module name. This did not work.

When I renamed my module to zs_adminviews which is far less pretty, it worked.

So, with:

function zs_admin_views_views_default_views_alter(&$views) {
  ...
}

... the function was not being called.

However, when I renamed the module, this function is being called:

function zs_adminviews_views_default_views_alter(&$views) {
  ...
}
RAWDESK’s picture

Same problem as #16 and #17
Sk8erPeter explained at this stackexchange a bit why it 's not working.

Therefore followed the offered alternative and implemented it inside a hook_update_N() inside a custom .install file :

<?php
function MYMODULE_update_7001() {

  $view = views_get_view('admin_views_node', TRUE);
  $display = $view->display['default'];

  /* Veld: Inhoud: Clone link */
  $display->display_options['fields']['clone_node']['id'] = 'clone_node';
  $display->display_options['fields']['clone_node']['table'] = 'node';
  $display->display_options['fields']['clone_node']['field'] = 'clone_node';
  $display->display_options['fields']['clone_node']['label'] = '';
  $display->display_options['fields']['clone_node']['element_label_colon'] = FALSE;
  views_save_view($view);
}

As such it become part of the upgrade path and lifecycle of our application, rather then being hosted by a feature.
Not ideal, but in attendance of a contrib solution, an acceptable alternative i believe.