Comments

dasjo’s picture

Version: 7.x-1.0-alpha2 » 7.x-1.x-dev

this should require implementing setBreadcrumb() for FacetapiUrlProcessorPrettyPaths.
see FacetapiUrlProcessorStandard::setBreadcrumb() and FacetapiUrlProcessor::setBreadcrumb()

ethnovode’s picture

Thanks for the quick answer. I'm not sure I have the skills, but I'll try to look into this today.

dasjo’s picture

sure ethnovode, i'd be blad to help you in creating such a patch

ethnovode’s picture

Hello again. I don't know how to use the encodePathSegment function. Also here is the function I copy/pasted from the original facetapi with very small modifications :

/**
   * Implements FacetapiUrlProcessorPrettyPaths::setBreadcrumb().
   */
  public function setBreadcrumb() {
    $breadcrumb = drupal_get_breadcrumb();

    // LINE ADDED FOR PRETTYPATH
    $facets = $this->adapter->getEnabledFacets();

    // Gets search keys and active items form the adapter.
    $keys = $this->adapter->getSearchKeys();
    $active_items = $this->adapter->getAllActiveItems();

    $item = menu_get_item();
    $last_load_func = is_array($item['load_functions']) ? end($item['load_functions']) : NULL;
    if (!empty($item['title']) && ((!$keys && $active_items) || ($keys && $last_load_func != 'menu_tail_load'))) {
      $last = end($breadcrumb);
      $this_page = l($item['title'], $item['href'], $item['localized_options']);
      if ($last != $this_page) {
        $breadcrumb[] = $this_page;
      }
    }


    // Initializes base breadcrumb query.
    $query = $this->params;
    unset($query[$this->filterKey]);

    // Adds the current search to the query.
    if ($keys) {
      // The last item should be text, not a link.
      $breadcrumb[] = $active_items ? l($keys, current_path(), array('query' => $query)) : check_plain($keys);
    }
    // Adds filters to the breadcrumb trail.
    $last = end($active_items);
    foreach ($active_items as $item) {
      $query[$this->filterKey][] = rawurlencode($item['field alias']) . ':' . $item['value'];

      // Replaces with the mapped value.
      $value = $this->adapter->getMappedValue($item['facets'][0], $item['value']);

      // The last item should be text, not a link.
      if ($last == $item) {
        $breadcrumb[] = !empty($value['#html']) ? $value['#markup'] : check_plain($value['#markup']);
      }
      else {
        // Appends the filter to the breadcrumb trail.
        //$breadcrumb[] = l($value['#markup'], current_path(), array('query' => $query, 'html' => !empty($value['#html'])));

        /*************
        ************** Lines added for prettypath *****************
        **********************************************************/
        $segment = $this->getPathSegment($facets[$item['field alias']], $value);
        $this->encodePathSegment($segment);
        echo'<pre>';print_r($segment);echo'</pre>';
        $breadcrumb[] = l($value['#markup'], $segment['alias'] . '/' . $segment['value'], array('html' => !empty($value['#html'])));
        
      }
    }

    // Sets the breadcrumb trail with h keys and filters.
    drupal_set_breadcrumb($breadcrumb);
  }
}

And for the convenience of the reader, here is the function I tried to use to get the correct value part of the segment :

protected function encodePathSegment(array &$segment) {
    // Default: <alias>/<value>

    // @todo: Make this pluggable?
    // Taxonomy special case: <alias>/<term-name>-<term-id>
    $facet = $segment['facet'];
    if ($facet['field type'] == 'taxonomy_term') {
      if ($term = taxonomy_term_load($segment['value'])) {
        $voc = taxonomy_vocabulary_load($term->vid);
        $segment['value'] = $this->prettyPath($term->name) . '-' . $term->tid;
      }
    }

    $segment['value'] = str_replace('/', '%2F', $segment['value']);
    $segment['alias'] = rawurlencode($segment['alias']);
  }

I'm a total noob in php so what I did is probably horrible. I could get an almost ok value using $segment['value']['#markup'] but I believe it really needs to go into that encode thing :)

dasjo’s picture

hey there,

no worries, if you are interested in learning a little PHP you definitely picked a tricky one :)

i'm not sure when in the logic breadcrumbs are called, but problem that we might run into is that $this->pathSegments would have to be set accordingly to what this line of the breadcrumb logic does:

      $query[$this->filterKey][] = rawurlencode($item['field alias']) . ':' . $item['value'];

for the other pretty path logic, this happens in fetchParams()

then you sould be able to use getFacetPath() in order to get the path where needed.

you might want to use $item['value] instead of $value here, i guess

$segment = $this->getPathSegment($facets[$item['field alias']], $value);

also you will want to implement pretty paths logic for

  // Adds the current search to the query.
    if ($keys) {
      // The last item should be text, not a link.
      $breadcrumb[] = $active_items ? l($keys, current_path(), array('query' => $query)) : check_plain($keys);
    }

when you have progress keep me updated / don't hesitate asking further questions and please try to post your code as a patch against 7.x-1.x so i can review it more easily & commit it once its finished

ethnovode’s picture

Thanks a lot ! I will take another shot this weekend (I hope).

ethnovode’s picture

      $query[$this->filterKey][] = rawurlencode($item['field alias']) . ':' . $item['value'];

I'm not really sure what to do with the logic so with this patch each breadcrumb is just one thing.

you might want to use $item['value] instead of $value here, i guess

That was it. Excellent!

also you will want to implement pretty paths logic for

  // Adds the current search to the query.
    if ($keys) {
      // The last item should be text, not a link.
      $breadcrumb[] = $active_items ? l($keys, current_path(), array('query' => $query)) : check_plain($keys);
    }

I believed this was for the search and not the facets ?

Thanks for your help, very much appreciated.

mrfelton’s picture

Status: Active » Needs work

This works to an extent. Each breadcrumb link does use the alias correctly. However, when you have multiple active facets, each breadcrumb link only only retains a single facet, rather than the trail of active facets before it.

dasjo’s picture

ethnovode, great to see you making progress so quickly!

i have pointed out the reasons for #8 in the first part of my comment in #5.
$this->pathSegments has to reflect all active facets at the current moment.

mrfelton’s picture

Status: Needs work » Needs review
StatusFileSize
new3 KB

Try this version.

mrfelton’s picture

Almost works... constructPath() messes up the order of the breadcrumbs due to it's use of ksort(). So instead of using constructPath I'm doing it manually now, which retains the correct breadcrumb order.

mrfelton’s picture

Status: Needs review » Needs work

Hmm. The ordering is still getting messed up. The links look correct, but when you click on one, the order of the breadcrumbs gets rearranged.

mrfelton’s picture

Status: Needs work » Needs review
StatusFileSize
new5.88 KB

Updated patch, ensures that the breadcrumbs are presented in the order that they are selected.

mrfelton’s picture

Updated patch fixes whitespace errors and squashes all of my previous commits into one. I've also reverted to using constructPath() since the ksort wasn't the problem.

ethnovode’s picture

Hello,
You could probably delete these 2 lines I added to build the path :

$params = $this->fetchParams();
$search_path = $params['q'];

I still have some troubles with the order of the breadcrumbs, but it is now much better thanks.

mrfelton’s picture

Yeah, think your right. Updated patch.

dasjo’s picture

thanks ethnovode & mrfelton for working on this!

can we set this to RTBC already? can you elaborate a bit on the breadcrumbs ordering issue?

mrfelton’s picture

I'm not sure about the ordering issue anymore. What we have now from #16 works perfectly for us. @ethnovode, can you elaborate?

ethnovode’s picture

I have about 10 facets and sometimes the breadcrumbs are in the right order, sometimes they are not. Last time I wanted to check where the problem came from, I ended up in the adapter file which was probably too far away. :) I'll check again soon to give you more precise informations.

Edit: For example, I got this order in my breadcrumb whereas "Essence" was clicked last (good order for the other 3) :
Essence/BMW/SERIE 3/Casablanca

Other than that everything works perfectly. I'm still trying to find the cause of this. At a moment I was pretty sure the facet array in the $segments was corresponding to another field but I can't reproduce and the order is still not right. Maybe I'm just crazy.

ethnovode’s picture

Status: Needs review » Reviewed & tested by the community

My ordering issue is probably not related to this patch. I'm still trying to find out how the order of the segments are being build for each facet and how it affects the order of the breadcrumbs :
Instead of having <segment1><segment2><segment3> in the URL, I have sometimes <segments3><segment1><segment2> for example. I tested this with and without the patch. I'll try to dig deeper in the getFacetPath function or above to see if we can build the $path another way.
The ordering is fine when I deactivate Pretty Paths.

And I don't know if it's related, but for example if I print $segments here :

protected function constructPath($basePath, array $segments) {
    // Sort to avoid multiple urls with duplicate content.
    echo('<pre>');print_r($segments);echo('</pre>');

I find some facet array not related to their "parents". For example :

[ville_08] => Array
        (
            [alias] => ville
            [value] => 08
            [facet] => Array
                (
                    [label] => État
                    [description] => Filter by État.

And of course ville is not the same facet as état

I set this patch RTBC but I may come back ! ;)

dasjo’s picture

Status: Reviewed & tested by the community » Fixed

#16 works for me as well, committed in ece1756 - thanks!
please create separate follow-up issues regarding sorting if appropriate.

Status: Fixed » Closed (fixed)

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