Django

Code

Changeset 5608

Show
Ignore:
Timestamp:
07/04/07 04:28:29 (1 year ago)
Author:
mtredinnick
Message:

unicode: Added unicode-aware slugify filter (in Python) and better non-ASCII
handling for the Javascript slug creator in admin. Can never be perfect here,
but this is more tolerant in many cases. Fixed #4365. Thanks, Bill de hÓra,
Baptiste, orestis@orestis.gr, Ahmet and Jonas for contributions to this.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/unicode/django/contrib/admin/media/js/urlify.js

    r4537 r5608  
     1var LATIN_MAP = 
     2{ 
     3    'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'à
     4': 'A', 'Æ': 'AE', 'Ç': 
     5    'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I', 
     6    'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö': 
     7    'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ý': 'Y', 'Þ': 'TH', 
     8    'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': 'a', 'À': 'a', 'Ã¥': 'a', 'Ê': 
     9    'ae', 'ç': 'c', 'Ú': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e', 'ì': 'i', 'í': 'i', 
     10    'î': 'i', 'ï': 'i', 'ð': 'o', 'ñ': 'n', 'ò': 'o', 'ó': 'o', 'ÃŽ': 'o', 'õ': 
     11    'o', 'ö': 'o', 'Þ': 'o', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ÃŒ': 'u', 'Ü': 'y', 
     12    'ß': 'th', 'ÿ': 'y', 
     13} 
     14var LATIN_SYMBOLS_MAP = 
     15{ 
     16    '©':'(c)', 
     17} 
     18var GREEK_MAP = 
     19{ 
     20    'α':'a', 'β':'b', 'γ':'g', 'ÎŽ':'d', 'ε':'e', 'ζ':'z', 'η':'h', 'Ξ':'8', 
     21    'ι':'i', 'κ':'k', 'λ':'l', 'ÎŒ':'m', 'Μ':'n', 'Ο':'3', 'ο':'o', 'π':'p', 
     22    'ρ':'r', 'σ':'s', 'τ':'t', 'Ï 
     23':'y', 'φ':'f', 'χ':'x', 'ψ':'ps', 'ω':'w', 
     24    'ά':'a', 'έ':'e', 'ί':'i', 'ό':'o', 'ύ':'y', 'ή':'h', 'ώ':'w', 'ς':'s', 
     25    'ϊ':'i', 'ΰ':'y', 'ϋ':'y', 'ΐ':'i', 
     26    'Α':'A', 'Β':'B', 'Γ':'G', 'Δ':'D', 'Ε':'E', 'Ζ':'Z', 'Η':'H', 'Θ':'8', 
     27    'Ι':'I', 'Κ':'K', 'Λ':'L', 'Μ':'M', 'Ν':'N', 'Ξ':'3', 'Ο':'O', 'Π':'P', 
     28    'Ρ':'R', 'Σ':'S', '΀':'T', 'Î¥':'Y', 'Ί':'F', 'Χ':'X', 'Κ':'PS', 'Ω':'W', 
     29    'Ά':'A', 'Έ':'E', 'Ί':'I', 'Ό':'O', 'Ύ':'Y', 'Ή':'H', 'Ώ':'W', 'Ϊ':'I', 
     30    'Ϋ':'Y' 
     31} 
     32var TURKISH_MAP = { 
     33    'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I', 'ç':'c', 'Ç':'C', 'ÃŒ':'u', 'Ü':'U', 
     34    'ö':'o', 'Ö':'O', 'ğ':'g', 'Ğ':'G', 
     35} 
     36// var RUSSIAN_MAP = 
     37// { 
     38// } 
     39 
     40var ALL_DOWNCODE_MAPS=new Array() 
     41ALL_DOWNCODE_MAPS[0]=LATIN_MAP 
     42ALL_DOWNCODE_MAPS[1]=LATIN_SYMBOLS_MAP 
     43ALL_DOWNCODE_MAPS[2]=GREEK_MAP 
     44ALL_DOWNCODE_MAPS[3]=TURKISH_MAP 
     45//ALL_DOWNCODE_MAPS[4]=RUSSIAN_MAP 
     46 
     47var Downcoder = new Object(); 
     48Downcoder.Initialize = function() 
     49{ 
     50    if (Downcoder.map) // already made 
     51        return ; 
     52    Downcoder.map ={} 
     53    Downcoder.chars = '' ; 
     54    for(var i in ALL_DOWNCODE_MAPS) 
     55    { 
     56        var lookup = ALL_DOWNCODE_MAPS[i] 
     57        for (var c in lookup) 
     58        { 
     59            Downcoder.map[c] = lookup[c] ; 
     60            Downcoder.chars += c ; 
     61        } 
     62     } 
     63    Downcoder.regex = new RegExp('[' + Downcoder.chars + ']|[^' + Downcoder.chars + ']+','g') ; 
     64} 
     65 
     66downcode= function( slug ) 
     67{ 
     68    Downcoder.Initialize() ; 
     69    var downcoded ="" 
     70    var pieces = slug.match(Downcoder.regex); 
     71    if(pieces) 
     72    { 
     73        for (var i = 0 ; i < pieces.length ; i++) 
     74        { 
     75            if (pieces[i].length == 1) 
     76            { 
     77                var mapped = Downcoder.map[pieces[i]] ; 
     78                if (mapped != null) 
     79                { 
     80                    downcoded+=mapped; 
     81                    continue ; 
     82                } 
     83            } 
     84            downcoded+=pieces[i]; 
     85        } 
     86    } 
     87    else 
     88    { 
     89        downcoded = slug; 
     90    } 
     91    return downcoded; 
     92} 
     93 
     94 
    195function URLify(s, num_chars) { 
    296    // changes, e.g., "Petty theft" to "petty_theft" 
    397    // remove all these words from the string before urlifying 
     98    s = downcode(s); 
    499    removelist = ["a", "an", "as", "at", "before", "but", "by", "for", "from", 
    5100                  "is", "in", "into", "like", "of", "off", "on", "onto", "per", 
     
    8103    r = new RegExp('\\b(' + removelist.join('|') + ')\\b', 'gi'); 
    9104    s = s.replace(r, ''); 
     105    // if downcode doesn't hit, the char will be stripped here 
    10106    s = s.replace(/[^-\w\s]/g, '');  // remove unneeded chars 
    11107    s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces 
     
    14110    return s.substring(0, num_chars);// trim to first num_chars chars 
    15111} 
     112 
  • django/branches/unicode/django/template/defaultfilters.py

    r5597 r5608  
    116116 
    117117def slugify(value): 
    118     "Converts to lowercase, removes non-alpha chars and converts spaces to hyphens" 
    119     # Don't compile patterns as unicode because \w then would mean any letter. 
    120     # Slugify is effectively a conversion to ASCII. 
    121     value = re.sub('[^\w\s-]', '', value).strip().lower() 
     118    """ 
     119    Normalizes string, converts to lowercase, removes non-alpha chars and 
     120    converts spaces to hyphens. 
     121    """ 
     122    import unicodedata 
     123    value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') 
     124    value = unicode(re.sub('[^\w\s-]', '', value).strip().lower()) 
    122125    return re.sub('[-\s]+', '-', value) 
    123126slugify = stringfilter(slugify) 
  • django/branches/unicode/tests/regressiontests/defaultfilters/tests.py

    r5591 r5608  
    6868u'jack-jill-like-numbers-123-and-4-and-silly-characters' 
    6969 
     70>>> slugify(u"Un \xe9l\xe9phant \xe0 l'or\xe9e du bois") 
     71u'un-elephant-a-loree-du-bois' 
     72 
    7073>>> stringformat(1, u'03d') 
    7174u'001'