It may be the same issue as #338258: CSV exporting of multiple values in fields reported some time ago for 5.x

If there is a multiple-valued CCK text field with values like English, German, French, etc., it will be exported to CSV as EnglishGermanFrench. Would it be possible to add a delimiter like with taxonomy fields? Configurable delimiter would be nice, but just comma-separated is good as well.

Thanks for these excellent features.

CommentFileSizeAuthor
#22 views_bonus_multiple_formatter.patch3.55 KBneclimdul

Comments

alex.k’s picture

It is probably directly related to how Views formats these fields. Taxonomy does use a configurable delimiter, whereas multi-valued CCK fields would be rendered with < ul>< li>value< /li>.... - so markup is stripped and we end up with just text in CSV.

neclimdul’s picture

That explains a lot. I was never sure what that issue was trying to do.

I'll see if there's something we can do.

amanire’s picture

Has there been any progress on this issue? Currently, it is concatenating values without any separation.

amanire’s picture

Category: feature » bug

I am recategorizing this as a bug, since concatenating values without any separation renders the output difficult to read and impossible to analyze in an application like Excel.

servantleader’s picture

Version: 6.x-1.0-beta1 » 6.x-1.0-beta4

Has anyone found a work around for this issue or anything that will work?

gintass’s picture

Subscribing

Mixologic’s picture

Subscribing

dieter’s picture

hi, I fixed this in D6 as follows (probably not the cleanest way to do this, but it works)

function template_preprocess_views_bonus_export_csv(&$vars) {
  drupal_set_header('Content-type: text/csv; charset=utf-8');

  // TODO Replace items with themed_rows.
  _views_bonus_export_shared_preprocess($vars);

  if ($vars['options']['quote']) {
    $vars['seperator'] = '","';
    $replace_value = '""';
  }
  else {
    $vars['seperator'] = ',';
    $replace_value = '';
  }

  foreach ($vars['themed_rows'] as $i => $values) {
    foreach ($values as $j => $value) {
          // START CHANGES DIETER
          $value = str_replace('</div>', '||', $value);
          if (substr_count($value, '||') < 2) {
             // get rid of superfluous separators
             $value = str_replace('||', '', $value);
          } else { //remove trailing separator
             $value = substr($value, 0, strlen($value)-2);
          }
          // END CHANGES DIETER

      $vars['themed_rows'][$i][$j] = str_replace('"', $replace_value, decode_entities(strip_tags($value)));
    }
  }
}
Branndon’s picture

Where do I paste that?

dieter’s picture

Just replace the function in modules/views_bonus/ export/views_bonus_export.module

neclimdul’s picture

I'm trying to work something out for this along with #552172: Accept fields that render XML node structure.

sayuri’s picture

Thanks so much for that solution, dieter. It works perfectly for me in D5.18 with Views Bonus v5.x-1.2-alpha2. In that case, you need to insert the code in modules/views_bonus/views_bonus_export.module as below:


/**
 *  Main Function to export a view as CSV
 */
function theme_views_bonus_export_csv($view, $nodes) {
 
...

  // one row for each node
  foreach ($nodes as $node) {
    $values = array();
    foreach ($view->field as $field) {
      if ($fields[$field['id']]['visible'] !== false) {
        $value = views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view);
        
        // START CHANGES DIETER
         $value = str_replace('</div>', '||', $value);
         if (substr_count($value, '||') < 2) {
           // get rid of superfluous separators
           $value = str_replace('||', '', $value);
         } else { //remove trailing separator
             $value = substr($value, 0, strlen($value)-2);
         }
        // END CHANGES DIETER
        
        $values[] = '"' . str_replace('"', '""', decode_entities(strip_tags($value))) . '"';
      }
    }
    print implode($comma, $values) ."\r\n";
  }
  module_invoke_all('exit');
  exit;
}

grguth’s picture

Subscribing

BetaTheta’s picture

subscribing

sphopkins’s picture

This patch works on my web app. Hope it makes it into the full release eventually.

alex.k’s picture

The fix in #8 works for D6, thank you very much for posting.

lukus’s picture

The fix in #8 has helped me too .. thanks.

I'm a bit concerned that I've had to alter the module directly. Is there any chance of this functionality being build into a release?

alex.k’s picture

@lukus - you can put this function in your theme's template.php, just call it themename_preprocess_views_bonus_export_csv()

lukus’s picture

@alex.k, thanks for the heads-up I'll make sure I do that.

neclimdul’s picture

Status: Active » Closed (duplicate)
dafeder’s picture

Since discussion at http://drupal.org/node/552172 is still purely XML-related I'm posting this here. #8 didn't work for me, it removed some of my field-delineating quote marks and rendered the CSV file unreadable. This modification worked for me (added and renamed in theme template.php). $delimeter can of course be any character(s) you want.

function THEMENAME_preprocess_views_bonus_export_csv(&$vars) {
  // TODO Replace items with themed_rows.
  _views_bonus_export_shared_preprocess($vars);

  $vars['seperator'] = $vars['options']['seperator'];

  // Special handling when quoted values are involved.
  if ($vars['options']['quote']) {
    $wrap = '"';
    $replace_value = '""';
  }
  else {
    $wrap = '';
    $replace_value = '';
  }

  // Format header values.
  foreach ($vars['header'] as $key => $value) {
    $vars['header'][$key] = $wrap . str_replace('"', $replace_value, decode_entities(strip_tags($value))) . $wrap;
  }
  // Format row values.
  $delimeter = ', ';
  foreach ($vars['themed_rows'] as $i => $values) {
    foreach ($values as $j => $value) {
      $value = str_replace('</div>', $delimeter, $value);
      if (substr_count($value, $delimeter) < 2) {
         // get rid of superfluous separators
         $value = str_replace($delimeter, '', $value);
      } else { //remove trailing separator
         $value = substr($value, 0, strlen($value)-2);
      }
      $vars['themed_rows'][$i][$j] = $wrap . str_replace('"', $replace_value, decode_entities(strip_tags($value))) . $wrap;
    }
  }
neclimdul’s picture

Title: Use a delimiter for multiple valued CCK fields in CSV » Provide for cck fields that render custom node structure.
Status: Closed (duplicate) » Needs work
StatusFileSize
new3.55 KB

I'm not going to commit that as it doesn't provide for rows that legitimately have divs that are not multiple cck fields. Its just not going to happen.

However there is actually a subtle difference now that I remember the other issue better so I'm reopening this. This patch is just closely dependent on a fix to #552172: Accept fields that render XML node structure as I'll explain later.

I've attached a patch that kinda shows an approach I'm interested in working with. Where the other issue comes into play is when the plugin version of the theme function gets called and provides some sort of html/xml/etc structure, its still going to be stripped out.

So, this patch doesn't fix this issue yet but I do want some feedback on how it would for people.

Approach summary(for non patch readers)

We provide a CCK formatter you would choose for the field. This would most likely be override the formatter for the default display so the HTML version of the view would use the normal formatter. Maybe we provide some fallback method for non views export display styles, this is already sort of supported by the patch. Then using a proxy theme function we'll provide a number of theme function alternatives matching a pattern. I think the code setting up the pattern is pretty self explanatory as to the pattern:

    $theme_pattern = array(
      'views_bonus_export_format_multiple__' . $view->name . '__' . $display_id . '__' . $type,
      'views_bonus_export_format_multiple__' . $view->name . '__' . $display_id,
      'views_bonus_export_format_multiple__' . $view->name . '__' . $type,
      'views_bonus_export_format_multiple__' . $display_id . '__' . $type,
      'views_bonus_export_format_multiple__' . $display_id,
      'views_bonus_export_format_multiple__' . $type,
      'views_bonus_export_format_multiple',
    );

where $type is a magic export plugin value like csv, xml, xls, doc.

So, each plugin would have some basic fallback code for providing multiple field rendering and then further site specific customization can be done at the theme layer if needed and follows a theme setup that should be familiar to views developers.

boabjohn’s picture

Howdy:

I have applied the patch of #22 to my views_bonus/export install and got success for hunk 2.

I might be missing the concept though as it would seem if you're going to provide some modification as a cck formatter, wouldn't that need to be patched against cck? At any rate, opening the content type>cck field in question I don't see a new formatter option as a result of the patch.

And the View still shows multiple values concatenated.

So: not sure why this has been sitting idle for so long...it would seem like a pretty core aspect of functionality.

The strategy outlined above seems reasonable to me, although I don't quite get how you plan to reach over into cck world from a Views plugin.

FWIW it seems like you could hook into the native Views process that knows about "Grouping" multiple values and just extend the idea with a new option: "Choose Delimiter for Multiple Values"

No idea what that might involve, but I just note that the logic for single vs multiple values seems to be already partially available.

In any event:

Thanks for the module and your work. Looking forward to a productive resolution asap.

ahabman’s picture

I must have an updated version of the module. Doing a straight copy and paste of #8 built a blank csv. To apply the patch from #8 to version "6.x-1.1" I ended up with the following.

function template_preprocess_views_bonus_export_csv(&$vars) {
  // TODO Replace items with themed_rows.
  _views_bonus_export_shared_preprocess($vars);

  $vars['seperator'] = $vars['options']['seperator'];

  // Special handling when quoted values are involved.
  if ($vars['options']['quote']) {
    $wrap = '"';
    $replace_value = '""';
  }
  else {
    $wrap = '';
    $replace_value = '';
  }

  // Format header values.
  foreach ($vars['header'] as $key => $value) {
    $output = decode_entities(strip_tags($value));
    if ($vars['options']['trim']) {
      $output = trim($output);
    }
    $vars['header'][$key] = $wrap . str_replace('"', $replace_value, $output) . $wrap;
  }

  // Format row values.
  foreach ($vars['themed_rows'] as $i => $values) {
    foreach ($values as $j => $value) {
    
      // START CHANGES DIETER
      $value = str_replace('</div>', '||', $value);
      if (substr_count($value, '||') < 2) {
         // get rid of superfluous separators
         $value = str_replace('||', '', $value);
      } else { //remove trailing separator
         $value = substr($value, 0, strlen($value)-2);
      }
      // END CHANGES DIETER
          
      $output = decode_entities(strip_tags($value));
      if ($vars['options']['trim']) {
        $output = trim($output);
      }
      $vars['themed_rows'][$i][$j] = $wrap . str_replace('"', $replace_value, $output) . $wrap;
    }
  }
}
islandlinux’s picture

Subscribing

kazah’s picture

subscribing...

neclimdul’s picture

Issue summary: View changes
Status: Needs work » Closed (outdated)