Forum: Rails France Partager un méthode partout dans Rail

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
B935c7953e0d4c30b82fdee575163e6a?d=identicon&s=25 pierre.valade@gmail.com (Guest)
on 2007-07-29 18:28
(Received via mailing list)
Bonjour à tous pour mon premier message sur cette liste, étant un
nouvel utilisation (et déjà fan) de RoR.

Je voudrais partager une méthode qui permet de convertir les accents
en caractères correspondants non accentués.
Je l'utilise pour générer des url propres en redéfinissant la méthode
to_param

Dois-je placer ce code pour l'utiliser partout dans Rails ?

def self.normalize(str)
     n = str.chars.downcase.strip.to_s
     n.gsub!(/[àáâãäåāă]/,    'a')
     n.gsub!(/æ/,            'ae')
     n.gsub!(/[ďđ]/,          'd')
     n.gsub!(/[çćčĉċ]/,       'c')
     n.gsub!(/[èéêëēęěĕė]/,   'e')
     n.gsub!(/Æ’/,             'f')
     n.gsub!(/[ĝğġģ]/,        'g')
     n.gsub!(/[ĥħ]/,           'h')
     n.gsub!(/[ììíîïīĩĭ]/,    'i')
     n.gsub!(/[įıijĵ]/,        'j')
     n.gsub!(/[ķĸ]/,          'k')
     n.gsub!(/[łľĺļŀ]/,       'l')
     n.gsub!(/[ñńňņʼnŋ]/,      'n')
     n.gsub!(/[òóôõöøōőŏŏ]/,  'o')
     n.gsub!(/OE/,            'oe')
     n.gsub!(/Ä…/,             'q')
     n.gsub!(/[ŕřŗ]/,         'r')
     n.gsub!(/[śšşŝș]/,       's')
     n.gsub!(/[ťţŧț]/,        't')
     n.gsub!(/[ùúûüūůűŭũų]/,  'u')
     n.gsub!(/ŵ/,             'w')
     n.gsub!(/[ýÿŷ]/,         'y')
     n.gsub!(/[žżź]/,         'z')
     n.gsub!(/\s+/,            ' ')
     n.gsub!(/[^\sa-z0-9_-]/,   '')
     n
   end

Ensuite, je voudrais faire :
class XX < ActiveRecord::Base
  def to_param
    "#{id}-#{nom.gsub(/[^a-z1-9]+/i, '-')}"
  end
end

Merci par avance,

Cordialement,

Pierre.
B935c7953e0d4c30b82fdee575163e6a?d=identicon&s=25 Pierre Valade (Guest)
on 2007-07-29 18:30
(Received via mailing list)
Pardon, je corrige, ensuite je voudrais faire :

  def to_param
    "#{id}-#{nom.normalize.gsub(/[^a-z1-9]+/i, '-')}"
  end

Bien sur :)

Le 29/07/07, pierre.valade@gmail.com <pierre.valade@gmail.com> a écrit :
0fd845e7824e980053d4f12c37d89652?d=identicon&s=25 Guillaume "Zifro" DESRAT (Guest)
on 2007-07-29 23:25
(Received via mailing list)
Pour ma part, pour les _petites_ modifications du langage, je le place
à la fin de environment.rb (parce que pour, c'est une modification de
l'environnement...) ; si tu en as trop, mets les dans un module et
étend tes classes à partir de là.
Donc je te propose de rajouter ceci :

class ActiveRecord::Base
# tes modifications dans la classe
end


Mais peut-être que quelqu'un d'autre a une préférence pour une autre
solution.

Le 29/07/07, Pierre Valade<pierre.valade@gmail.com> a écrit :
> > nouvel utilisation (et déjà fan) de RoR.
> >      n.gsub!(/[àáâãäåāă]/,    'a')
> >      n.gsub!(/[łľĺļŀ]/,       'l')
> >      n.gsub!(/[žżź]/,         'z')
> > end
>
--
Guillaume DESRAT / Zifro AKA guillaumed
http://zlab.fr/
4a7982065027f6678cf86fd469d34f08?d=identicon&s=25 renaud morvan (Guest)
on 2007-07-30 04:05
(Received via mailing list)
La facon logique de faire serait d en faire une methode d instance de
String
ou du multicharset de Rails 1.2.
L inconvenient etant le risque de collision dans l espace de nommage et
le fait que String commence deja a etre pollue d une centaine de methode
plus ou moins utile.

 L autre possibilite est d en faire une methode statique de module, de
placer le module dans /lib avec un nom de fichier correspondant a la
version
underscore du nom du module afin que ce soit charge automatiquement par
rails. Exemlpe:

module Normalizer
  def self.execute(str)
    ....
  end
end

fichier normalizer.rb dans /lib, ensuite Normalizer.execute est
accessible
de partout dans rails
139b66112d2e2b4efafac2aefed01c2f?d=identicon&s=25 Yann KLIS (Guest)
on 2007-07-30 09:38
(Received via mailing list)
Ca n'est peut-être pas tout à fait "iso-fonctionnel", mais tu peux
essayer de remplacer tous tes appels à gsub par :

trans = Iconv.new('US-ASCII//TRANSLIT', 'utf-8')
trans.iconv str


++

yk

Le 29/07/07, pierre.valade@gmail.com<pierre.valade@gmail.com> a écrit :
B935c7953e0d4c30b82fdee575163e6a?d=identicon&s=25 pierre.valade@gmail.com (Guest)
on 2007-07-30 12:46
(Received via mailing list)
Merci pour vos réponses.

J'ai fait au plus simple.

J'ai ajouté dans environnement.rb les lignes suivantes :

class ActiveRecord::Base
  def url_propre(str)
     n = str.chars.downcase.strip.to_s
     n.gsub!(/[àáâãäåāă]/,    'a')
     n.gsub!(/æ/,            'ae')
     n.gsub!(/[ďđ]/,          'd')
     n.gsub!(/[çćčĉċ]/,       'c')
     n.gsub!(/[èéêëēęěĕė]/,   'e')
     n.gsub!(/Æ’/,             'f')
     n.gsub!(/[ĝğġģ]/,        'g')
     n.gsub!(/[ĥħ]/,           'h')
     n.gsub!(/[ììíîïīĩĭ]/,    'i')
     n.gsub!(/[įıijĵ]/,        'j')
     n.gsub!(/[ķĸ]/,          'k')
     n.gsub!(/[łľĺļŀ]/,       'l')
     n.gsub!(/[ñńňņʼnŋ]/,      'n')
     n.gsub!(/[òóôõöøōőŏŏ]/,  'o')
     n.gsub!(/OE/,            'oe')
     n.gsub!(/Ä…/,             'q')
     n.gsub!(/[ŕřŗ]/,         'r')
     n.gsub!(/[śšşŝș]/,       's')
     n.gsub!(/[ťţŧț]/,        't')
     n.gsub!(/[ùúûüūůűŭũų]/,  'u')
     n.gsub!(/ŵ/,             'w')
     n.gsub!(/[ýÿŷ]/,         'y')
     n.gsub!(/[žżź]/,         'z')
     n.gsub!(/\s+/,            ' ')
     n.gsub!(/[^a-zA-Z0-9]/,   '-')
     n.gsub!(/-+/,'-')
     n
   end
end

Attention, pensez à redémarrer votre serveur après avoir modifié
environnement.rb !

Puis dans mes modèles, j'utilise :

  def to_param
    "#{id}-#{url_propre(nom)}"
  end

Et c'est super :)

Pierre.

On 29 juil, 23:24, "Guillaume \"Zifro\" DESRAT"
A83a70aa42afa4c45563213e6ffc03ce?d=identicon&s=25 Eric Daspet (Guest)
on 2007-07-30 13:23
(Received via mailing list)
On 7/29/07, pierre.valade@gmail.com <pierre.valade@gmail.com> wrote:

> Bonjour à tous pour mon premier message sur cette liste, étant un
> nouvel utilisation (et déjà fan) de RoR.
>
> Je voudrais partager une méthode qui permet de convertir les accents
> en caractères correspondants non accentués.


J'ai une fonction similaire dans mes plugins. Attention toutefois, ta
fonction ne prend pas en compte les majuscules accentuées (le downcase
ne
fonctionne que pour l'ascii de base donc ta majuscule accentuée restera
telle quelle). Il te faudrait ajouter ça.
Si tu te contentes du français je te propose aussi d'épurer tes
expressions.
Plus tu en ajoutes plus ça prendra de temps. Si tu veux faire du
dynamique
avec to_param comme je le lis dans le fil de discussion, ta
normalisation
prendra effet plusieurs fois par page. Il vaudrait mieux ne faire que
l'utile.

Attention aussi à la méthode iconv. Elle est beaucoup plus rapide,
beaucoup
plus efficace, mais suivant les systèmes, le é peut donner soit e soit
e'
(avec l'apostrophe juste après). Perso dans ma fonction similaire j'ai
d'abord utilisé iconv, puis j'ai mis ce qui suit (ma méthode s'appelle
"to_ascii") :

   def to_ascii
      Iconv.new('ASCII//TRANSLIT', 'UTF-8').iconv(self)
   end
   if "é".to_ascii != "e"
      def to_ascii
         # ... remplacements avec gsub
      end
    end

Perso j'ai ajouté ça directement à String vu que je l'utilise à
plusieurs
endroits.




>
> Dois-je placer ce code pour l'utiliser partout dans Rails ?


Logiquement tu fais un plugin. Dans ton répertoire /vendor/plugins tu
fais
un nouveau répertoire avec un init.rb pour charger tout ça.
Après au choix, où tu fais un module qui étendra ton modèle, ou tu étend
ta
classe String (suivant que tu veux utiliser ça juste pour les urls de
rails
ou de manière plus générique)


--
Éric Daspet
http://eric.daspet.name/
B935c7953e0d4c30b82fdee575163e6a?d=identicon&s=25 pierre.valade@gmail.com (Guest)
on 2007-07-30 14:57
(Received via mailing list)
Eric, merci beaucoup pour ses précisions.

J'ai pas encore les réflexes d'une programmation 100% orientée objet.
J'avais pas pensé à étendre la classe String ;)
A99870c1391c39da2089649745965bda?d=identicon&s=25 Jean-François Trân (Guest)
on 2007-07-31 14:17
(Received via mailing list)
Guillaume :
> Pour ma part, pour les _petites_ modifications du langage,
> je le place à la fin de environment.rb (parce que pour, c'est une
> modification de l'environnement...) ; si tu en as trop, mets les
> dans un module et étend tes classes à partir de là.

Houlala, je trouve ça très crade, config/environment.rb est
réservé à la configuration (et d'ailleurs pour que ce soit plus clean,
dans Edge/2.0, on utilise(ra) des fichiers dans config/initializers/ )
et toute modification (aussi minime soit-elle) des classes de base
de Ruby ou de Rails devrait se faire àmha dans lib/ (ou dans un plugin
comme l'a dit Eric), dans un ou plusieurs fichiers au nom pertinent.

C'est encore plus vrai si on met son projet en open source.

> Donc je te propose de rajouter ceci :
>
> class ActiveRecord::Base
> # tes modifications dans la classe
> end
>
>
> Mais peut-être que quelqu'un d'autre a une préférence pour une
> autre solution.

clair. cf plus haut.

  -- Jean-François.

--
Ruby ( http://www.rubyfrance.org ) on Rails ( http://www.railsfrance.org
)
A99870c1391c39da2089649745965bda?d=identicon&s=25 Jean-François Trân (Guest)
on 2007-07-31 14:27
(Received via mailing list)
Pierre :
> Bonjour à tous pour mon premier message sur cette liste,
> étant un nouvel utilisation

salut et bienvenue, mais tu seras le seul dans ce cas, car
ici il n'y a que des utilisateurs de Rails.

>      n = str.chars.downcase.strip.to_s
>      n.gsub!(/[àáâãäåāă]/,    'a')
>      n.gsub!(/æ/,            'ae')

[snip : pleins de #gsub! ]

Pour compléter les dires de mes colistiers, si tu prends
l'option non Iconv, il faut pour des raisons de performances,
que tu minimises les appels à String#gsub! en utilisant aussi
String#tr!

Ensuite 2 remarques :

class XX < ActiveRecord::Base
 def to_param
   "#{id}-#{nom.gsub(/[^a-z1-9]+/i, '-')}"
 end
end

1/ ça suppose que tous tes modèles AR::B possèdent
un attribut 'nom'

2/ Si le nom est une chaîne vide (voire le résultat de la
normalization donne une chaîne vide), tu peux obtenir
des trucs comme "395-"

   -- Jean-François.

--
Ruby ( http://www.rubyfrance.org ) on Rails ( http://www.railsfrance.org
)
91eb330fb36d1e03c856574dfb77d2bc?d=identicon&s=25 Thibaut Barrère (thbar)
on 2007-08-09 00:26
(Received via mailing list)
Bonsoir,

>    def to_ascii
>       Iconv.new('ASCII//TRANSLIT', 'UTF-8').iconv(self)
>    end
>    if "é".to_ascii != "e"
>       def to_ascii
>          # ... remplacements avec gsub
>       end
>     end
>

A toutes fins utiles et vu que Iconv ne marche pas partout, j'ai de
mon côté ceci (dont je ne suis pas tout à fait satisfait, mais qui
marche raisonnablement bien dans mes cas):

====================
module DiacriticsFu
   def self.escape(str)

ActiveSupport::Multibyte::Handlers::UTF8Handler.normalize(str,:d).split(//
u).reject { |e| e.length > 1 }.join
  end
end
====================

Les tests:

====================
require File.dirname(__FILE__) + '/../spec_helper'
require 'diacritics_fu'

describe "DiacriticsFu.escape" do

  it "should remove the accents with grace" do
    DiacriticsFu::escape("éphémère").should eql("ephemere")
    DiacriticsFu::escape("éêèïîù").should eql("eeeiiu")
  end

  KNOWN_DIACRITICS = { "a" => "àäâ", "e" => "éèêë", "i" => "îï", "o"
=> "ôö", "u" => "üû", "c" => "ç",
                       "I" => "ÏÎ",  "E" => "ÊË", "n" => "ñ", "O" =>
"ÔÖ", "Y" => "Ÿ", "y" => "ÿ", "N" => "Ñ"  }

  KNOWN_DIACRITICS.each do |expected_replacement,originals|
    it "should transform any of '#{originals}' into
'#{expected_replacement}'" do
      originals.split(//).each do |original|
        DiacriticsFu.escape(original).should eql(expected_replacement)
      end
    end
  end
end
====================

C'est un besoin quand même assez répandu, est-ce que quelqu'un
connaîtune petite gem simple qui ferait ce genre de chose directement ?

-- Thibaut
This topic is locked and can not be replied to.