Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort special characters #4

Open
laportjo opened this issue Aug 2, 2017 · 11 comments
Open

Sort special characters #4

laportjo opened this issue Aug 2, 2017 · 11 comments
Assignees

Comments

@laportjo
Copy link

laportjo commented Aug 2, 2017

Hi Daniel,

Is there a way to sort correctly special characters in a list via the helper reference() ? For example, I have this list (excerpt) :

  • Abbaye
  • Bâtiment d'exposition
  • Palais
  • Édifice
  • Église

But I expect this order :

  • Abbaye
  • Bâtiment d'exposition
  • Édifice
  • Église
  • Palais

Thanks ! Your plugin is very wonderful.

@Daniel-KM
Copy link
Owner

You have to change the line https://github.com/Daniel-KM/Reference/blob/master/views/helpers/Reference.php#L287 with " utf8_roman_ci" (or add an option to manage it cleanly).

@laportjo
Copy link
Author

It doesn't seem to work. I get the same list order.

@Daniel-KM
Copy link
Owner

So you can sort the resulting array via php just after that.

@silviaegt
Copy link

silviaegt commented Nov 13, 2018

Hi @Daniel-KM, thank you so much for your tool. We find it very useful!
However we encountered the same problem as @laportjo (cf. http://sandbox.colmex.mx/~silvia/omeka25/references/creator#number)
We also changed the Reference.php line you mentioned (we tried utf8_roman_ci; utf8_general_ci; and utf8mb4_unicode_ci [following this post]), but it didn't have any effect.

Also, we don't quite understand what you mean by: "or add an option to manage it cleanly" nor with " you can sort the resulting array via php just after that"

Thanks in advance for any help you could provide us :)

@Daniel-KM
Copy link
Owner

The file to edit is the view one : https://github.com/Daniel-KM/Omeka-plugin-Reference/blob/master/views/public/common/reference-list.php. It's hard to resolve, because it's a mix of locale format of the server, of the database and of php.
As always with cms, copy this file in your theme (in common/reference-list.php), in order to keep the plugin clean and your site maintainable.

@zerocrates
Copy link

MySQL should be handling this sorting fine, whether under the default Omeka collation of utf8_unicode_ci or with utf8_general_ci.

I think the issue here is actually happening because of the PHP-side "re-sorting" that happens when the strip option is enabled. You can turn off strip and thereby rely only on the MySQL-side sorting, or you can replace the uksort in the Reference helper with something like this: (you'll need the PHP intl extension, though)

$collator = new Collator('root');
uksort($references, array($collator, 'compare'));

But, this would also require a change in the logic for generating headings: it will currently "see" the change from A to Á (and back again to A if the accented word appears in the middle of the list) and output extra headings.

@Daniel-KM Daniel-KM self-assigned this Nov 19, 2018
@Daniel-KM
Copy link
Owner

Thanks, I'll give it a try.

@rodyoukai
Copy link

Hi all,

I solve the problem.

First, Comment this line:

https://github.com/Daniel-KM/Omeka-plugin-Reference/blob/master/views/helpers/Reference.php#L128

Because natcasesort does not support diacritics.

Second add this function on top of https://github.com/Daniel-KM/Omeka-plugin-Reference/blob/master/views/public/common/reference-list.php

<?php
function normaliza ($cadena){
    $originales = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿŔŕ';
    $modificadas = strtoupper('aaaaaaaceeeeiiiidnoooooouuuuy').'bsaaaaaaaceeeeiiiidnoooooouuuyybyRr';
    $cadena = utf8_decode($cadena);
    $cadena = strtr($cadena, utf8_decode($originales), $modificadas);
    return utf8_encode($cadena);
}

Third apply this function in reference-list.php in lines 22 & 60, as follows:

$first_char = normaliza(function_exists('mb_substr') ? mb_substr($reference, 0, 1) : substr($reference, 0, 1));

Fourth step... enjoy!!!

@DBinaghi
Copy link

Sorry, @rodyoukai, but I've tried your method and don't see any change.
Could you please provide a working example, like a live repository?
thanks

@DBinaghi
Copy link

DBinaghi commented Apr 15, 2020

$collator = new Collator('root');
uksort($references, array($collator, 'compare'));

This solution works very well for me, thanks. I've also changed the headings functions, like this:

// Get the list of headers.
$collator = new Collator('root');
uksort($references, array($collator, 'compare'));
$alphabet = array('A','B','C','Ĉ','D','E','È','F','G','Ĝ','H','Ĥ','I','J','Ĵ','K','L','M','N','O','P','Q','R','S','Ŝ','T','U','Ŭ','V','X','Y','W','Z');
$letters = array('number' => false) + array_fill_keys($alphabet, false);
foreach ($references as $reference => $referenceData):
	$first_char = mb_substr($reference, 0, 1, 'UTF-8');
	if (strlen($first_char) == 0 || preg_match('/\W|\d/u', $first_char)):
		$letters['number'] = true;
	else:
		$first_char = mb_strtoupper($first_char, 'UTF-8');;
		$letters[$first_char] = true;
	endif;
endforeach;
$pagination_list = '<ul class="pagination_list">';
foreach ($letters as $letter => $isSet):
	$letterDisplay = ($letter == 'number' ? '#0-9' : $letter);
	if ($isSet):
		$pagination_list .= sprintf('<li class="pagination_range"><a href="#%s">%s</a></li>', $letter, $letterDisplay);
	else:
		$pagination_list .= sprintf('<li class="pagination_range"><span>%s</span></li>', $letterDisplay);
	endif;
endforeach;

Similarly, then, for the references list.
Hope this helps.

@DBinaghi
Copy link

DBinaghi commented Jun 8, 2020

$alphabet = array('A','B','C','Ĉ','D','E','È','F','G','Ĝ','H','Ĥ','I','J','Ĵ','K','L','M','N','O','P','Q','R','S','Ŝ','T','U','Ŭ','V','X','Y','W','Z');
$letters = array('number' => false) + array_fill_keys($alphabet, false);

I've amended my fork, with a config option to add a custom alphabet to be used for skip links headers:

$alphabet = (get_option('reference_list_alphabet') != '' ? explode(' ', get_option('reference_list_alphabet')) : array_fill_keys(range('A', 'Z'), false)); 
$letters = array('number' => false) + array_fill_keys($alphabet, false);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants