Hi, would be great if we could add support for different date format when using date filter facets. Right now the formats are hardcoded.

The hour formats is using 12-hour format but here in Sweden we user 24-hour clock and i think moste of the world use 24-hour format.

Mabye convert function facetapi_format_timestamp to a theme function so it atleast could be ovverriden in theme layer.

What you think?

Comments

cpliakas’s picture

Title: Make date format customizable or themeable » Make date format more easily customizable
Version: 7.x-1.x-dev » 7.x-2.x-dev

I think this request makes sense, but I am not sure about the best way to approach this. Each "gap" (i.e. year, month, day, etc.) has a different format, so it would get a little verbose if we defined different date types via the hook_date_format_types() system and forced users to select which format to use on each gap. Let's discuss and see what makes sense.

Just a point of clarification, though, the dates are not actually hard coded although overriding is probably not trivial. In a custom module you can implement hook_facetapi_facet_info_alter() and change the "map callback" for date facets and implement whatever logic you need to display dates how you want them. Untested example code is posted below:

/**
 * Implements hook_facetapi_facet_info_alter().
 */
function mymodule_facetapi_facet_info_alter(array &$facet_info, array $searcher_info) {
  foreach ($facet_info as $name => $facet) {
    if ('facetapi_map_date' == $facet['map callback']) {
      $facet_info[$name]['map callback'] = 'mymodule_map_date';
    }
  }
}

/**
 * Custom mapping callback.
 */
function mymodule_map_date(array $values) {
  $map = array();
  foreach ($values as $value) {
    $range = explode(' TO ', trim($value, '{[]}'));
    if (isset($range[1])) {
      $gap = facetapi_get_date_gap($range[0], $range[1]);
      $map[$value] = mymodule_format_date($range[0], $gap);
    }
  }
  return $map;
}

/**
 * Custom date formatter, change as necessary.
 */
function mymodule_format_date($date, $gap = FACETAPI_DATE_YEAR) {
  $timestamp = strtotime($date);
  switch ($gap) {
    case FACETAPI_DATE_MONTH:
      return format_date($timestamp, 'custom', 'F Y', 'UTC');

    case FACETAPI_DATE_DAY:
      return format_date($timestamp, 'custom', 'F j, Y', 'UTC');

    case FACETAPI_DATE_HOUR:
      return format_date($timestamp, 'custom', 'g A', 'UTC');

    case FACETAPI_DATE_MINUTE:
      return format_date($timestamp, 'custom', 'g:i A', 'UTC');

    case FACETAPI_DATE_SECOND:
      return format_date($timestamp, 'custom', 'g:i:s A', 'UTC');

    default:
      return format_date($timestamp, 'custom', 'Y', 'UTC');
  }
}

Because a viable workaround exists without having to patch the module I am marking this as a 2.x feature. In addition, It would be a great contributed module to provide a more flexible solution for the 1.x branch of Facet API.

cpliakas’s picture

Version: 7.x-2.x-dev » 7.x-1.x-dev
Category: feature » task

Pushing back to 7.x-1.x. The API should be cleaner, and can be done in a backwards compatible way. The goal isn't to provide a method to do this via the core Facet API module's GUI pages, but rather to make it easier for contrib to provide this functionality or developers to override it.

cpliakas’s picture

Status: Active » Needs review
StatusFileSize
new1.73 KB

The attached patch adds a bit of a cleanup. It reduces the logic needed to override the date formatting callback.

/**
 * Implements hook_facetapi_facet_info_alter().
 */
function mymodule_facetapi_facet_info_alter(array &$facet_info, array $searcher_info) {
  foreach ($facet_info as $name => $facet) {
    if ('facetapi_map_date' == $facet['map callback']) {
      $facet_info[$name]['map options'] = array('callback' => 'mymodule_format_timestamp');
    }
  }
}

/**
 * Custom date formatter, change as necessary.
 */
function mymodule_format_timestamp($timestamp, $gap = FACETAPI_DATE_YEAR) {
  switch ($gap) {
    case FACETAPI_DATE_MONTH:
      return format_date($timestamp, 'custom', 'F Y', 'UTC');

    case FACETAPI_DATE_DAY:
      return format_date($timestamp, 'custom', 'F j, Y', 'UTC');

    case FACETAPI_DATE_HOUR:
      return format_date($timestamp, 'custom', 'g A', 'UTC');

    case FACETAPI_DATE_MINUTE:
      return format_date($timestamp, 'custom', 'g:i A', 'UTC');

    case FACETAPI_DATE_SECOND:
      return format_date($timestamp, 'custom', 'g:i:s A', 'UTC');

    default:
      return format_date($timestamp, 'custom', 'Y', 'UTC');
  }
}
cpliakas’s picture

Status: Needs review » Needs work

Marking as needs work since the "callback" option is a bit non-descriptive. It should be "format callback" for code redability.

cpliakas’s picture

Status: Needs work » Needs review

Made the change. The hook_facetapi_facet_info_alter() callback would now look as follows.

/**
 * Implements hook_facetapi_facet_info_alter().
 */
function mymodule_facetapi_facet_info_alter(array &$facet_info, array $searcher_info) {
  foreach ($facet_info as $name => $facet) {
    if ('facetapi_map_date' == $facet['map callback']) {
      $facet_info[$name]['map options'] = array('format callback' => 'mymodule_format_timestamp');
    }
  }
}
cpliakas’s picture

StatusFileSize
new1.75 KB

Forgot to attach patch ...

cpliakas’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

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

freakalis’s picture

I had to modify your example code in #5 a bit to make it work for me.

/**
* Implements hook_facetapi_facet_info_alter().
*/
function mymodule_facetapi_facet_info_alter(array &$facet_info, array $searcher_info) {
  foreach ($facet_info as $name => $facet) {
    if ($facet['map options']['map callback'] =='facetapi_map_date') {
      $facet_info[$name]['map options']['format callback'] = 'mymodule_format_timestamp';
    }
  }
}
jmary’s picture

Issue summary: View changes
StatusFileSize
new7.19 KB

Another option is to use the module facetapi_bonus and the filter configuration
filter configuration

enable "Rewrite facet items via callback function"

and create a module with a function like in the following example :


/**
 * @param $build
 * @param $settings
 * We transform a year of birth into age with " years old" behind.
 */
function MYMODULE_facet_items_alter(&$build, &$settings) {
  // dpm($settings);
  // dpm($build);
  if ($settings->facet == "field_basic_info:field_birthday") {
    foreach($build as $key => $value) {
      $year = $build[$key]["#markup"];
      // dpm($year);
      $datetime1 = new DateTime('now');
      $datetime2 = new DateTime($year);
      $interval = $datetime1->diff($datetime2);
      $age = $interval->format('%y years old');
      $build[$key]["#markup"] = $age;
    }
  }
}