Seltsames Verhalten der Hooks css_alter
am 29.10.2015 - 12:20 Uhr in
Hallöchen,
ich möchte einen CSS-Pfad korrigieren bevor dieser in den Header-Ausgegeben wird. Der dazu passende Hook ist wohl hook_css_alter( &$css ).
Da ich die Änderung global in all meinen Seiten aktivieren möchte, habe ich den entsprechden Hook eines (eigenen) Moduls welches ich in allen Themes einsetzte, entsprechend erweiter. Die Funktionaltität wird in dem Modul-Hook auch durchgeführt, geht aber scheinbar komplett verloren. Erst wenn ich den entsprechenden Hook direkt im Theme einbaue und hier den seleben Code einfüge greift die Änderung.
Anders ausgedrückt: Der Hook des Modules modifiziert das CSS-Array, lasse ich dieses zur Kontrolle erneut im Theme-Hook ausgeben enthält es das original Eingangs-Array (daher keine Modifikationen).
So sieht der Code zu den Hook-Funktionen aus:
function MODULE_css_alter( &$css )
{
foreach ($css as $key => $value) {
if ($value['type'] === 'external') {
$css[$key]['data'] = str_replace(array('|'),array('%7C'),$css[$key]['data']);
}
}
// An dieser Stelle ist das Array definitiv so aufgebaut wie es gewuenscht wird!
}
.
.
.
function THEME_css_alter( &$css )
{
// Hier sind die zuvor im Module-Hook vorgenommenen Aenderungen nicht mehr vorhanden
foreach ($css as $key => $value) {
if ($value['type'] === 'external') {
$css[$key]['data'] = str_replace(array('|'),array('%7C'),$css[$key]['data']);
}
}
}
Die beiden Hooks werden definitv ausgeführt und zwar in der oben angegebenen Reihenfolge.
Auch ein deutlich komplexerer Umbau des CSS-Arrays (inkl. unset oder clone) bringt nichts.
Da ich hier den Pfad des CSS ('data') ändere, habe ich das Array schon entsprechend umgebaut, so dass anschliessend nur noch der korrekte Eintrag vorhanden ist:
[http://fonts.googleapis.com/css?family=Open+Sans:600,regular%7COpen+Sans+Condensed:300%7COswald:700%7CRoboto:500,700&subset=latin] => Array
(
[type] => external
[group] => 100
[weight] => 0.019
[every_page] =>
[media] => all
[preprocess] => 1
[data] => http://fonts.googleapis.com/css?family=Open+Sans:600,regular%7COpen+Sans...
[browsers] => Array
(
[IE] => 1
[!IE] => 1
)
)
Mein Problem besteht also darin, dass THEME_css_alter() immer wieder das original Array reingereicht bekommt.
Alle anderen Modifikationen der CSS im Hook des Modules greifen jedoch. Also alles der Form:
$css = drupal_add_css( .... )
Frage: Hat noch jemand ein Idee woran es liegen kann?
Danke (:-
- Anmelden oder Registrieren um Kommentare zu schreiben
Das ist vermutlich eine Frage
am 29.10.2015 - 13:46 Uhr
Das ist vermutlich eine Frage der Gewichtung. Die Module werden alphabetisch durchlaufen, sofern sie das gleiche Gewicht haben. Wenn Du also den Pfad änderst und ein späteres Modul ihn wieder zurück setzt, kann das natürlich nicht gehen. Das Theme wird immer nach den Modulen angesprungen und dort würde ich die Änderung auch plazieren.
Die Module werden in
am 29.10.2015 - 14:56 Uhr
Die Module werden in passenden Reihenfolge durchlaufen. Das hab ich ja beschrieben, dass zunächst die Hook-Funktion des Modules und dann die Hook-Funktion des Themes angesteuert wird.
In der Hook-Funktion des Modules wird zunächst eine Änderung durchgeführt (an der per Ref übergebenen Variable), diese Änderung kommt aber in der danach ausgeführten Hook_funktion des Themes nicht mehr an.
Die eine Frage ist ob es noch
am 29.10.2015 - 15:47 Uhr
Die eine Frage ist ob es noch weitere Module außer Deinem gibt die hook_css_alter ansprechen und ob diese ggf. nach Deinem Modul zur Ausführung kommen
Die andere Frage ist warum Du die Änderung nicht gleich im Theme statt im Modul vornimmst wenn Sie dort greift
Keines (meiner) anderen
am 29.10.2015 - 17:14 Uhr
Keines (meiner) anderen Module macht die genannte Änderung Rückgängig.
Ich kann natürlich das Code-Schnippsel immer in das jeweilige Theme kopieren. Das wiederstrebt mir aber, den ich möchte derartige Dinge gerne Zentral in einem meiner Core-Module durchführen. Dadurch deploy ich diese Änderungen automatisch auf alle von mir betreuten Webseiten, ohne jedes Theme einzeln anpacken zu müssen.
Ergänzend zu meiner ersten Beschreibung:
Ich hatte ein ähnliches Problem beim D7-Core schon einmal. Damals hing es, an dem per Value übergebenen Parameter.
Ich hab das hier so ausführlich gepostet, weil ich hoffte das evtl. jemandem etwas in dem Zusammenhang auffällt.
Welches Modul bringt denn
am 29.10.2015 - 17:03 Uhr
Welches Modul bringt denn dieses CSS ein, das Du ändern willst?
Modul = fontyourface
am 29.10.2015 - 17:12 Uhr
Modul = fontyourface
Und das baut den URL Parameter zum Pullen der Fonts von Google-Font so zusammen, das er nicht HTML5 komform ist.
Die Browser kommen damit klar. Aber es ist eine Unschönheit im HTML-Validator, und da es der letzte Fehler ist den die Validatoren auf meinen Seiten anmeckern würd ich es gerne eliminieren (o:-
FontYourFace in der Datei google_font_api, Zeile 119:
$url = $base . implode( '|', $families) . '&subset=' . implode(',', $all_subsets);
Anstelle des '|' gehört da ein '%7C' hin, aber ich will nicht im Source des fremden Modules rumwurschteln (wegen Updates ect.).
Ungefär so sieht das aus, was das Modul an der Stelle genneriert:
<link type="text/css" rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans+Condensed:300|Open+Sans:regular&subset=latin" media="all" />
(Um das Pipe zwischen 300 und Open geht's dabei).
Na, %7C ist doch ein |. Wozu
am 29.10.2015 - 18:31 Uhr
Na, %7C ist doch ein |. Wozu also der Aufstand?
Nur weil die meisten Browser
am 29.10.2015 - 19:26 Uhr
Nur weil die meisten Browser mit einem & anstelle eines *amp; in der URL klar kommen, entspricht es noch lange nicht den Definitionen. Gleiches gilt für das Pipe-Zeichen.
Das hier meint der Validator dazu:
Fehler: Bad value “//fonts.googleapis.com/css?family=Open+Sans:600,regular|Open+Sans+Condensed:300|Oswald:700|Roboto:500,700&subset=latin” for attribute “href” on element “link”: Illegal character in query: not a URL code point.
Drupal liefert aber doch
am 29.10.2015 - 18:58 Uhr
Drupal liefert aber doch UFT8-Code aus und zeigt das auch im header. Daher ist das Pipe-Zeichen wohl definiert. Der Ersatzcode ist also nicht notwendig.
Das ist alles richtig!
am 29.10.2015 - 20:02 Uhr
Das ist alles richtig.
Es geht auch nicht um Funktionalität des CSS-Querys. Einige Kunden haben aber die Angewohnheit ihre Seite mittels Validator zu checken. Und unter anderem der in diesen Kreisen sehr populäre "seitwert.de" meckert es an.
Ansonsten ging es mir in dem Threat auch nicht um die Frage ob der Code valide ist, sondern worin das aus meiner Sicht seltsame Verhalten der Drupal-Hooks begründet liegt.
Wie bereits geschrieben, ich bekomme die gewünschte Funktionalität ja API-Konform zum laufen aber eben nicht an der Stelle an der es aus meiner Sicht möglich seien müsste (tiefer in den den Modulen).
Also ich hab das bei mir mal
am 30.10.2015 - 07:31 Uhr
Also ich hab das bei mir mal ausprobiert mit einem Google-Font über font-your-face. Wenn ich hier $css[key]['data'] in hook_css_alter in meinem Modul ändere, dann greift das auch noch im Theme.
ok
am 30.10.2015 - 07:55 Uhr
Danke.
Wenn ich dich recht verstanden habe, hast Du auch nur [data] geändert. Daher, den Key des Assoc-Array hast Du nicht gändert, und denooch funktioniert alles so wie erwartet?
Das ist gut, dann kann ich zumindes diese (recht umständliche) Fehlerquelle ausschliessen.
ich folgendes
am 30.10.2015 - 08:09 Uhr
ich folgendes gemacht:
function test_fyf_css_alter(&$css)
{
$css['http://fonts.googleapis.com/css?family=Cabin:500,600,700&subset=latin']['data'] = "test";
}
Das kam dann auch so im Theme an.