Programok által használt név

szabozoltan69 képe

A Drupal 7 adminisztrációs felület több részén előkerül olyasmi, hogy beírhatunk egy címet, majd megjelenik egy ehhez tartozó "Programok által használt név", ami egy (címnek megfelelő) ASCII karakterlánc. Azonban az ékezetes betűk _ jellel vannak pótolva. Megoldható az, hogy inkább az ékezetmentes változatra történjen a csere, és ezt ne kelljen mindig manuálisan helyretenni?

Drupal verzió: 
Fórum: 
Sk8erPeter képe

A machine name-re való átírogatásra vonatkozó objektumot és metódusokat a /misc/machine-name.js fájlban láthatod.
Ha pl. megnyitod az /admin/structure/types/add oldalt, akkor ez is betöltődik.
A transliterate függvény alakítja át a szöveget, ez pedig egy replace patternt (settings.replace_pattern) vár, meg egy karaktert, amire le kellene cserélni a megfelelő karaktereket (settings.replace).

Így néz ki a függvény:

  /**
   * Transliterate a human-readable name to a machine name.
   *
   * @param source
   *   A string to transliterate.
   * @param settings
   *   The machine name settings for the corresponding field, containing:
   *   - replace_pattern: A regular expression (without modifiers) matching
   *     disallowed characters in the machine name; e.g., '[^a-z0-9]+'.
   *   - replace: A character to replace disallowed characters with; e.g., '_'
   *     or '-'.
   *   - maxlength: The maximum length of the machine name.
   *
   * @return
   *   The transliterated source string.
   */
  transliterate: function (source, settings) {
    var rx = new RegExp(settings.replace_pattern, 'g');
    return source.toLowerCase().replace(rx, settings.replace).substr(0, settings.maxlength);
  }

A default replace pattern és a karakter, amire cserél, látszik a
jQuery.extend(Drupal.settings, .......)
résznél a forráskódban:
"replace_pattern":"[^a-z0-9_]+","replace":"_"

Nos, a fenti transliterate függvényt át kellene kicsit alakítanod.
Legegyszerűbb az lenne, ha egy ékezetátalakító metódust betennél ebbe az objektumba, hasonlóan a transliterate-hez, majd ezt a függvényt a transliterate-en belül utolsó sor ELŐTT meghívnád úgy, hogy a "source" változót adod át neki paraméterül.

Tehát ilyesmire gondolok (a kommentbe tett pontok azt jelzik, hogy előtte kód vagy komment van):

  // ........
  transliterate: function (source, settings) {
    var rx = new RegExp(settings.replace_pattern, 'g');
    // IDE KERÜL a plusz függvényhívás
    source = this.remove_accents(source);
    // innentől ismét az eredeti kód...
    return source.toLowerCase().replace(rx, settings.replace).substr(0, settings.maxlength);
  }, // FIGYELEM! Ha ezután teszed, ne felejtsd el a vesszőt!!
 
  // ........
  remove_accents: function (source) {
     // ide kerül az ékezet eltávolítására szolgáló kód!!
     // ...
     return source;
  }
};

Ékezet átalakításával kapcsolatban hasznos lehet:
http://4rapiddev.com/javascript/javascript-remove-vietnamese-accents/

Persze a remove_vietnamese_accents függvénynevet változtasd meg, és tegyél bele innen kimaradt ékezetes karaktereket is, mint pl. az ó, ö, ő, ü, ű.

4
0
alippai képe

Majdnem tökéletes válasz, még arra ügyelj, hogy ne a /misc/machine-name.js fájlt írd át, hanem hozz létre egy modult, ami a hook_js_alter() függvényt valósítja meg.
Így nem kell minden Drupal frissítésnél újra elvégezni a változtatást.

6
0

Lippai Ádám
young element

Sk8erPeter képe

+1, köszönöm a kiegészítést!
Eddig csak 6-osra fejlesztettem komolyabban, a hook_js_alter() függvényt még nem használtam, de nagyon hasznos, és valóban így a helyes, nem a core modulok és egyéb fájlok módosítgatása!

1
0
szabozoltan69 képe

Köszönöm én is a válaszokat! Sikerrel jártam, legalábbis nyersen kicserélve a régit az újra minden tökéletes.

Ez volt a régi fájl, ez meg lett az új. A legalja az érdekes.

Küzdök ezzel a hook_js_alter-rel, de eddig nem vezetett sikerre.
Arra gondoltam, hogy a saját mybartik sminkembe felveszem a template.php-be a következő függvényt:

  1. function mybartik_js_alter(&$javascript) {
  2. $javascript['misc/machine-name.js'] = drupal_get_path('theme', 'mybartik') . '/js/machine-name.js';
  3. }

De ezzel nem működik (pedig nem felejtettem el a gyorstár törlését). A favágó módon viszont megy (ha kicserélem a misc/machine-name.js fájlt az újra). Tudnátok segíteni, hogy hogy szokás ezt intelligensen megoldani? A js registryvel is kéne ügyeskedni valamit?
0
0
szantog képe

Tedd fel a devel modult, és nézd meg milyen kulcs-érték párokkal van tárolva a javascript. Ha csak egy sima mezei array(0 => 'path'), akkor ilyesmi kell:

  1. unset($javascript['misc/machine-name.js']);
  2. $javascript[] = drupal_get_path('theme', 'mybartik') . '/js/machine-name.js';

vagy inkább

  1. foreach ($javascript as $key => $filename) {
  2. if ($filename == 'misc/machine-name.js') {
  3. $javascript[$key] = drupal_get_path('theme', 'mybartik') . '/js/machine-name.js'
  4. }
  5. }

Lecsekkolni, hogy mi van a $javascriptben arra a dsm($javascript) tök jó. Nézd meg azért mindenképpen, mert sejtésem szerint a settingst is valahol itt hordozza, és akkor nem lesz jó, amiket fentebb írtam.

0
0

----
Rájöttem, miért kérdezek olyan ritkán a drupal.hu-n. Amíg szedem össze az infokat a kérdéshez, mindig rájövök a megoldásra.

szabozoltan69 képe

Még több segítség/tudás kéne, hogy a "lecserélem az eredeti fájlt" helyett szebb módon tudjam megoldani a "programok által használt név" ékezetekkel is bánni tudó kialakítását. Fent van a devel modul, és megnéztem a dsm($javascript)-et, de nem látszik benne a misc/machine-name.js sehol, pedig azt használja a drupal, nem az általam (a sminkbe) betettet. Itt van a látható dsm($javascript), ami egy olyan oldalon hívódik meg, ami épp használja a machine-name.js szkriptet.

Az is lehet gond, hogy nem az adminisztrációs sminkkel dolgozom.

0
0
szantog képe

hoppa van egy kis szivas, kb zöldséget vadásztunk idáig
egyrészt jobban nem is nyúlhattam volna mellé a javascript tömbbel, de legalább ezt is megtudtuk.
másrészt meg ez nem egy classic drupal_add_js, hanem egy form elementhez egy process callbackben hozzácsapott js. @see form_process_machine_name

Szóval ezt eleve nem js_alterből kéne bántani, hanem _element_info_alterből.

  1. /**
  2.  * Implements hook_element_info_alter();
  3.  */
  4. function mymodule_element_info_alter(&$type) {
  5. foreach ($type['machine_name']['#process'] as $key => $process) {
  6. // Eltakaritjuk az eredeti form_machine_name processt, a sajatunkat fogjuk hasznalni
  7. if ($process == 'form_process_machine_name') {
  8. $type['machine_name']['#process'][$key] = 'mymodule_process_machine_name';
  9. }
  10. }
  11. }
  12.  
  13. /**
  14.  * A custom machine_name element process function to change transliteration method js.
  15.  */
  16. function mymodule_process_machine_name ($element, &$form_state) {
  17. // Eloszor athajtjuk az eredeti form processen, nem kinyirni akartuk az eredeti process, csak belebabralni.
  18. $element = form_process_machine_name($element, &$form_state)
  19.  
  20. foreach ($element['#attached']['js'] as $key => $js) {
  21. if ($js == 'misc/machine-name.js') {
  22. $element['#attached']['js'][$key] = drupal_get_path('module', 'mymodule') . '/js/machine-name.js';
  23. }
  24. }
  25.  
  26. return $element;
  27. }

Ja, a módosított js-t ne a sminkedbe tegyed, hanem a modulodhoz. Ha netán a modul anélkül a smink nélkül lesz használva, akkor sem fog eltörni.

1
0

----
Rájöttem, miért kérdezek olyan ritkán a drupal.hu-n. Amíg szedem össze az infokat a kérdéshez, mindig rájövök a megoldásra.

szabozoltan69 képe

Köszönöm a fejtágítást! Egyelőre vákuumban van a "modulom" szó, merthogy nem terveztem új modult készíteni (csak sminket), de majd akkor átgondolom.

0
0
Sk8erPeter képe

szantog, kutakodásod nem volt haszontalan, sőt, köszi, ez alapján, meg a korábbiak alapján elkészítettem egy első változatát a modulnak. "Utólagos engedelmeddel" az általad leírt részt is felhasználtam.

Teszt:
"Árvíztűrő tükörfúrógép típus"

ELŐTTE a generált machine name:
_rv_zt_r_t_k_rf_r_g_p_t_pus

content type machine name

UTÁNA (drush pm-enable machine_name_mod) a generált machine name:
arvizturo_tukorfurogep_tipus

content type machine name with removed accents

A működő modul elérhető itt.

Kódja:

machine_name_mod.info

  1. name = Machine Name Modifier
  2. description = Remove accents from generated machine name.
  3. package = Custom modules
  4. version = 1.0
  5. core = 7.x

machine_name_mod.module

  1. <?php
  2. <?php
  3.  
  4. /**
  5.  * @file
  6.  * A module for removing accents from the automatically generated content type machine name.
  7.  *
  8.  * @see http://drupal.hu/forum/programok-által-használt-név/15726
  9.  * @see http://drupal.hu/comment/64353#comment-64353
  10.  *
  11.  * @author Sk8erPeter
  12.  */
  13.  
  14. /**
  15.  * Implements hook_element_info_alter();
  16.  *
  17.  * Alter the element type information returned from modules.
  18.  * A module may implement this hook in order to alter the element type defaults defined by a module.
  19.  *
  20.  * @see http://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_element_info_alter/7
  21.  */
  22. function machine_name_mod_element_info_alter(&$type) {
  23. foreach ($type['machine_name']['#process'] as $key => $process) {
  24. // Eltakaritjuk az eredeti form_machine_name processt, a sajatunkat fogjuk hasznalni
  25. if ($process == 'form_process_machine_name') {
  26. $type['machine_name']['#process'][$key] = 'machine_name_mod_process_machine_name';
  27. }
  28. }
  29. }
  30.  
  31. /**
  32.  * A custom machine_name element process function to change transliteration method js.
  33.  */
  34. function machine_name_mod_process_machine_name($element, &$form_state) {
  35. // Eloszor athajtjuk az eredeti form processen, nem kinyirni akartuk az eredeti process-t, csak belebabralni.
  36. $element = form_process_machine_name($element, $form_state);
  37.  
  38. foreach ($element['#attached']['js'] as $key => $js) {
  39. if ($js == 'misc/machine-name.js') {
  40. $element['#attached']['js'][$key] = drupal_get_path('module', 'machine_name_mod') . '/js/machine-name.js';
  41. }
  42. }
  43.  
  44. return $element;
  45. }

js/machine-name.js

  1. // Modified by Sk8erPeter
  2.  
  3. (function ($) {
  4.  
  5. /**
  6.   * Attach the machine-readable name form element behavior.
  7.   */
  8. Drupal.behaviors.machineName = {
  9. /**
  10.   * Attaches the behavior.
  11.   *
  12.   * @param settings.machineName
  13.   * A list of elements to process, keyed by the HTML ID of the form element
  14.   * containing the human-readable value. Each element is an object defining
  15.   * the following properties:
  16.   * - target: The HTML ID of the machine name form element.
  17.   * - suffix: The HTML ID of a container to show the machine name preview in
  18.   * (usually a field suffix after the human-readable name form element).
  19.   * - label: The label to show for the machine name preview.
  20.   * - replace_pattern: A regular expression (without modifiers) matching
  21.   * disallowed characters in the machine name; e.g., '[^a-z0-9]+'.
  22.   * - replace: A character to replace disallowed characters with; e.g., '_'
  23.   * or '-'.
  24.   */
  25. attach: function (context, settings) {
  26. var self = this;
  27. $.each(settings.machineName, function (source_id, options) {
  28. var $source = $(source_id, context).addClass('machine-name-source');
  29. var $target = $(options.target, context).addClass('machine-name-target');
  30. var $suffix = $(options.suffix, context);
  31. var $wrapper = $target.parents('.form-item:first');
  32. // All elements have to exist.
  33. if (!$source.length || !$target.length || !$suffix.length || !$wrapper.length) {
  34. return;
  35. }
  36. // Skip processing upon a form validation error on the machine name.
  37. if ($target.hasClass('error')) {
  38. return;
  39. }
  40. // Figure out the maximum length for the machine name.
  41. options.maxlength = $target.attr('maxlength');
  42. // Hide the form item container of the machine name form element.
  43. $wrapper.hide();
  44. // Determine the initial machine name value. Unless the machine name form
  45. // element is disabled or not empty, the initial default value is based on
  46. // the human-readable form element value.
  47. if ($target.is(':disabled') || $target.val() != '') {
  48. var machine = $target.val();
  49. }
  50. else {
  51. var machine = self.transliterate($source.val(), options);
  52. }
  53. // Append the machine name preview to the source field.
  54. var $preview = $('<span class="machine-name-value">' + machine + '</span>');
  55. $suffix.empty()
  56. .append(' ').append('<span class="machine-name-label">' + options.label + ':</span>')
  57. .append(' ').append($preview);
  58.  
  59. // If the machine name cannot be edited, stop further processing.
  60. if ($target.is(':disabled')) {
  61. return;
  62. }
  63.  
  64. // If it is editable, append an edit link.
  65. var $link = $('<span class="admin-link"><a href="#">' + Drupal.t('Edit') + '</a></span>')
  66. .click(function () {
  67. $wrapper.show();
  68. $target.focus();
  69. $suffix.hide();
  70. $source.unbind('.machineName');
  71. return false;
  72. });
  73. $suffix.append(' ').append($link);
  74.  
  75. // Preview the machine name in realtime when the human-readable name
  76. // changes, but only if there is no machine name yet; i.e., only upon
  77. // initial creation, not when editing.
  78. if ($target.val() == '') {
  79. $source.bind('keyup.machineName change.machineName', function () {
  80. machine = self.transliterate($(this).val(), options);
  81. // Set the machine name to the transliterated value.
  82. if (machine != options.replace && machine != '') {
  83. $target.val(machine);
  84. $preview.text(machine);
  85. $suffix.show();
  86. }
  87. else {
  88. $suffix.hide();
  89. $target.val(machine);
  90. $preview.empty();
  91. }
  92. });
  93. // Initialize machine name preview.
  94. $source.keyup();
  95. }
  96. });
  97. },
  98.  
  99. /**
  100.   * Transliterate a human-readable name to a machine name.
  101.   *
  102.   * @param source
  103.   * A string to transliterate.
  104.   * @param settings
  105.   * The machine name settings for the corresponding field, containing:
  106.   * - replace_pattern: A regular expression (without modifiers) matching
  107.   * disallowed characters in the machine name; e.g., '[^a-z0-9]+'.
  108.   * - replace: A character to replace disallowed characters with; e.g., '_'
  109.   * or '-'.
  110.   * - maxlength: The maximum length of the machine name.
  111.   *
  112.   * @return
  113.   * The transliterated source string.
  114.   */
  115. transliterate: function (source, settings) {
  116. var rx = new RegExp(settings.replace_pattern, 'g');
  117. // MOD: we remove the accents
  118. source = this.remove_accents(source);
  119. //
  120. return source.toLowerCase().replace(rx, settings.replace).substr(0, settings.maxlength);
  121. },
  122.  
  123. /**
  124.   * Replace all occurrences of the search string with the replacement string
  125.   *
  126.   * @see http://4rapiddev.com/javascript/javascript-remove-vietnamese-accents/
  127.   */
  128. str_replace: function (search, replace, str){
  129. var ra = replace instanceof Array, sa = str instanceof Array, l = (search = [].concat(search)).length, replace = [].concat(replace), i = (str = [].concat(str)).length;
  130. while(j = 0, i--)
  131. while(str[i] = str[i].split(search[j]).join(ra ? replace[j] || "" : replace[0]), ++j < l);
  132. return sa ? str : str[0];
  133. },
  134.  
  135. /**
  136.   * Remove the accents from a string
  137.   *
  138.   * @see http://drupal.hu/comment/63091#comment-63091
  139.   * @see http://4rapiddev.com/javascript/javascript-remove-vietnamese-accents/
  140.   *
  141.   * @param source
  142.   * A string which we will remove the accents from.
  143.   */
  144. remove_accents: function (source) {
  145. var accents_arr= new Array(
  146. "à","á","ạ","ả","ã","â","ầ","ấ","ậ","ẩ","ẫ","ă",
  147. "ằ","ắ","ặ","ẳ","ẵ","è","é","ẹ","ẻ","ẽ","ê","ề",
  148. "ế","ệ","ể","ễ",
  149. "ì","í","ị","ỉ","ĩ",
  150. "ò","ó","ọ","ỏ","õ","ô","ồ","ố","ộ","ổ","ỗ","ơ",
  151. "ờ","ớ","ợ","ở","ỡ", "ö","ő",
  152. "ù","ú","ụ","ủ","ũ","ư","ừ","ứ","ự","ử","ữ", "ü","ű",
  153. "ỳ","ý","ỵ","ỷ","ỹ",
  154. "đ",
  155. "À","Á","Ạ","Ả","Ã","Â","Ầ","Ấ","Ậ","Ẩ","Ẫ","Ă",
  156. "Ằ","Ắ","Ặ","Ẳ","Ẵ",
  157. "È","É","Ẹ","Ẻ","Ẽ","Ê","Ề","Ế","Ệ","Ể","Ễ",
  158. "Ì","Í","Ị","Ỉ","Ĩ",
  159. "Ò","Ó","Ọ","Ỏ","Õ","Ô","Ồ","Ố","Ộ","Ổ","Ỗ","Ơ",
  160. "Ờ","Ớ","Ợ","Ở","Ỡ", "Ö","Ő",
  161. "Ù","Ú","Ụ","Ủ","Ũ","Ư","Ừ","Ứ","Ự","Ử","Ữ", "Ü","Ű",
  162. "Ỳ","Ý","Ỵ","Ỷ","Ỹ",
  163. "Đ"
  164. ),
  165.  
  166. no_accents_arr= new Array(
  167. "a","a","a","a","a","a","a","a","a","a","a",
  168. "a","a","a","a","a","a",
  169. "e","e","e","e","e","e","e","e","e","e","e",
  170. "i","i","i","i","i",
  171. "o","o","o","o","o","o","o","o","o","o","o","o",
  172. "o","o","o","o","o", "o","o",
  173. "u","u","u","u","u","u","u","u","u","u","u", "u","u",
  174. "y","y","y","y","y",
  175. "d",
  176. "A","A","A","A","A","A","A","A","A","A","A","A",
  177. "A","A","A","A","A",
  178. "E","E","E","E","E","E","E","E","E","E","E",
  179. "I","I","I","I","I",
  180. "O","O","O","O","O","O","O","O","O","O","O","O",
  181. "O","O","O","O","O", "O","O",
  182. "U","U","U","U","U","U","U","U","U","U","U", "U","U",
  183. "Y","Y","Y","Y","Y",
  184. "D"
  185. );
  186.  
  187. return this.str_replace(accents_arr,no_accents_arr,source);
  188. }
  189. };
  190.  
  191. })(jQuery);
2
0
mib képe

Haj

Összedobtam neked(meg másoknak) egy modulban ha érdekel. Sajnos ide nem tudom feltölteni, de egy admin talán tud majd segíteni ebben.

0
0
Sk8erPeter képe

szantog lényegében az alapját már megmutatta itt korábban. :)
Ehhez csak a megfelelően módosított JS-fájlt kell hozzácsapni, és kész is a modul.

Ettől függetlenül feltölthetnéd a tiédet is legalább valami (ingyenes) tárhelyre (akár Dropbox), és megoszthatnád, ha gondolod.

0
0
Sk8erPeter képe

Közben én is mellékeltem egy saját változatot, lásd korábban.

0
0