Jest jakiś sposób na dodanie CSS dla pojedynczej strony / węzła?


79

Oczyszczam moje duże zwariowane arkusze stylów (prawdopodobnie związane z przyszłym pytaniem) i zastanawiam się, jak najlepiej dodać niestandardowy CSS do określonego węzła lub strony.

W szczególności strona główna mojej witryny jest stroną panelową i ma wiele różnych stylów. Obecnie CSS jest właśnie dołączony do głównego arkusza stylów motywu.

Czy istnieje sposób, aby powiedzieć „jeśli jest to węzeł Foo, to dodaj foo.css”? Czy szukam CSS Injector ?

I może być zainteresowany w uogólniając to z innymi węzłami / sekcje / etc, ale w tej chwili po prostu chcę, aby obsłużyć ten jeden element.

Co ostatecznie skończyłem.

Korzystam z podtematu Zen i podczas czytania poprzez template.php odkryłem, że istnieje jakiś skomentowany kod do dołączania arkuszy stylów warunkowych. Poniższy kod zrobił dokładnie to, czego potrzebowałem:

if (drupal_is_front_page()) {
  drupal_add_css(path_to_theme() . "/foo.css", 'theme','all'); 
}

(Linia 80 w standardowym pliku Zen template.php, FWIW.)



utworzyć page--front.tpl.phpipage.tpl.php
M ama D

Odpowiedzi:


69

Jest to coś, co zrobiłbym za pomocą kodu, ale to dlatego, że tak właśnie robię.

W template.php będziesz chciał coś takiego:

function MYTHEME_preprocess_node($vars) {
  if (drupal_get_path_alias("node/{$vars['#node']->nid}") == 'foo') {
    drupal_add_css(drupal_get_path('theme', 'MYTHEME') . "/css/foo.css");
  }
}

Zamień foo na wartości związane z twoim własnym kodem.


więc czy na stronie głównej użyłbyś if(drupal_is_front_page()) {zamiast if(drupal_get_path_alias [etc]?
epersonae

Tak, warunki zależą wyłącznie od Ciebie. Możesz po prostu $vars['#node']->nid == $nidsprawdzić, jeśli chcesz.
Odszyfruj

8
Odszyfruj, nie można znaleźć błędu w kodzie. Ale mam nadzieję, że nie masz nic przeciwko, żebym ci powiedział, że jeśli nie mówisz o konfiguracji uprawnień Drupala, sposób, w jaki odgrywasz swoją rolę, powinien być sposób, w jaki się rzucasz. ;-)
środę

2
Do twojej wiadomości, używam Drupala 7 i stwierdziłem, że $vars['elements']['#node']->nidzamiast tego muszę użyć w wyszukiwaniu aliasu. Wygląda na to, że w najnowszym Drupalu 7 nie ma #nodekorzenia vars.
Wes Johnson

czy nie powinien mieć funkcji wyprzedzającej MYTHEME__preprocess_node ($ vars) Widzę cały tam kod tylko pod względem funkcji?
pal4life


16

Utwórz kontekst dla swojej strony / sekcji, a następnie użyj modułu Zasoby kontekstowe , aby załadować CSS i / lub javascript dla danego kontekstu.

Kontekst:

Kontekst pozwala zarządzać warunkami kontekstowymi i reakcjami dla różnych części witryny. Możesz myśleć o każdym kontekście jako o „sekcji” Twojej witryny. Dla każdego kontekstu możesz wybrać warunki, które aktywują ten kontekst i wybrać różne aspekty Drupala, które powinny reagować na ten aktywny kontekst.

Pomyśl o warunkach jako o zestawie reguł sprawdzanych podczas ładowania strony, aby zobaczyć, jaki kontekst jest aktywny. Wszelkie reakcje związane z aktywnymi kontekstami są następnie uruchamiane.

Kontekst Dodaj zasoby:

Kontekstowe dodawanie zasobów pozwala to zrobić. Ma łatwy w użyciu interfejs użytkownika, który pozwala to wszystko robić bez pisania kodu. Ponieważ używa narzędzi ctools, wszystko to można również eksportować.


Używam kontekstowego dodawania zasobów dosłownie w każdej witrynie, którą tworzę - jeśli twoja do kontekstu (która napędza każdą sekcję moich kompilacji) Dodaj zasoby jest idealna!
electblake

13

Jeśli jest to niewielka ilość CSS, być może zastanawiasz się nad wyborem selektorów CSS na podstawie węzła i włączeniem css do CSS motywu? Drupal 7 zapewnia selektor body.page-node-NODEID, a Zen dla Drupal 6 zapewnia podobne klasy CSS ciała.


że w zasadzie to, co było robić ... i to prawie 200 linii, więc wydawało się, że to dobry pomysł, aby przenieść go gdzie indziej. (tak, prawdopodobnie powinien być krótszy. to może być osobny krok.)
epersonae

Z drugiej strony, twoja odpowiedź zainspirowała mnie do przeczytania template.php w moim (Zen dziecko), co doprowadziło mnie do ostatecznej odpowiedzi.
epersonae

7

Możesz utworzyć niestandardowy moduł i użyć hook_preprocess_node () do selektywnego ładowania arkuszy stylów na podstawie identyfikatora węzła.

Oto przykład:

function MYMODULE_preprocess_node($vars) {
  $nid = 3;
  if (arg(0) == 'node' && is_numeric(arg(1)) && arg(1) == $nid) {
    drupal_add_css(drupal_get_path('theme', 'MYTHEME') . "/foo.css");
  }
}

Zamień MYMODULE na nazwę swojego modułu i zamień MYTHEME na nazwę motywu zawierającego plik css.


hook_init () działa przy każdym ładowaniu strony i często wiele razy (AHAH), dlaczego więc nie użyć hook_preprocess_node () (w kompozycji lub w module), który działa tylko, gdy renderowany jest węzeł?
Odszyfruj

Dobrze, nie wiedziałem, że init był ładowany wiele razy.
Camsoft,

Odszyfrowałem, poprawiłem mój przykład, aby użyć funkcji wstępnego przetwarzania. Wciąż się uczę!
Camsoft,

Kolejne pytanie brzmiałoby: po co używać argumentu arg (1) dla nid, gdy zmienne węzłów są przekazywane przez $ vars :), co prowadzi do następnego pytania, w jaki sposób różni się to od mojej odpowiedzi: p
Odszyfruj

Chyba powinienem był przeczytać dokumentację hook_preprocess_node (). Masz całkowitą rację. Epersonae, proponuję zaakceptować odpowiedź Rozszyfrowania.
Camsoft,

7

Jeśli kryteria, dla których dodanie stylu CSS zależy od niektórych właściwości węzła, zaimplementowałbym MYTHEME_preprocess_node(&$variables); jedną z wartości przekazywanych do funkcji jest $variables['node'](zauważ, że nie jest $variables['#node']).

MYTHEME_preprocess_node(&$variables) {
  if ($variables['node']->nid == 3) {
    drupal_add_css(drupal_get_path('theme', 'MYTHEME') . "/foo.css");
  }
}

Jeśli kryteria nie zależą od żadnych właściwości węzła, to zaimplementowałbym MYTHEME_preprocess_page(&$variables); $variables['node']zawiera obiekt węzła, jeśli wyświetlana strona jest stroną węzła. W Drupal 6 również pobiera się funkcja procesu $variables['is_front'], ale w Drupal 7 ta sama zmienna nie jest przekazywana; jeśli chcesz wiedzieć, czy strona jest stroną pierwszą, musisz użyć drupal_is_front_page().

MYTHEME_preprocess_page(&$variables) {
  if ($variables['is_front']) {
    drupal_add_css(drupal_get_path('theme', 'MYTHEME') . "/foo.css");
  }
}

5

Aby to zrobić z poziomu administratora, zajrzałbym do modułu CSS . Dodaje pole, w którym można dodać CSS do stron node/addi node/edit.

CSS:

Moduł CSS dodaje, dla użytkowników z wystarczającymi uprawnieniami i włączonymi węzłami, pole CSS na stronie tworzenia węzła.

Użytkownicy mogą wstawiać reguły CSS w polu węzła CSS, a reguły te zostaną przeanalizowane podczas przeglądania węzła.

W ten sposób doświadczeni użytkownicy CSS mogą tworzyć złożone projekty oparte na CSS dla zawartości węzłów.

Ważne: pamiętaj, że uprawnienia do edycji CSS powinny być przyznawane tylko zaufanym użytkownikom (administratorom). Złośliwi użytkownicy, którzy mają to uprawnienie, mogą popsuć projekt witryny i wprowadzić problemy związane z bezpieczeństwem (XSS).


3

CodePerNode jest świetny, ale instalacja CSS Injector jest prostsza (nie wymaga bibliotek). Moduł pozwala menedżerowi zawartości dynamicznie dodawać CSS do określonych stron, bez dotykania kodu PHP lub plików INFO. 15777 instalacji nie może się mylić - jest to dowód społecznościowy, że moduł działa. CSS jest również buforowany przy użyciu zwykłego systemu buforowania.


2

Ponieważ używasz już paneli, może być łatwiej po prostu dodać swój styl CSS jako styl panelu dla każdego regionu panelu strony głównej. Możesz zdefiniować niestandardowe znaczniki i użyć go ponownie w swojej witrynie.

Możesz także przejść do sekcji Ogólne reguły wariantu menedżera stron na swojej stronie głównej. Jest tutaj sekcja dodawania identyfikatorów CSS i reguł tylko dla bieżącego panelu.

Uwaga: to wszystko jest w D7, więc może być tak, że takie podejście jest lepiej obsługiwane przez Panele niż w poprzednich wersjach.


2

/ * Przykład użycia motywu bartik do dodawania css na podstawie typu zawartości * /

function bartik_preprocess_node(&$variables) {
if(!empty($variables['node'])) {
    if($variables['node']->type == 'my_custom_content_type')
    {
      drupal_add_css(drupal_get_path('theme', 'any_theme_name') . "/css/foo.css");   
    }
  }
  // Some other code here
}

2

Spróbuj dodać to do pliku „template.php”:

function mytheme_preprocess_page (&$variables)
{
  if (drupal_is_front_page()) {
    drupal_add_css(drupal_get_path('theme','mytheme'). '/css/front.css');
  } 
}

Zamień „mytheme” na nazwę katalogu motywów, a „/css/front.css” na ścieżkę do pliku CSS.

Aby wyłączyć plik „front.css” z innych stron, spróbuj dodać do „template.php”:

function hook_css_alter(&$css) {
  if (!drupal_is_front_page()) {
    unset($css[drupal_get_path('theme', 'mytheme') . '/css/front.css']);
  }
}

Ponownie zamień „mytheme” na nazwę katalogu motywów.

Jeśli chcesz usunąć ustawienie „styles.css” ze strony głównej, po prostu połącz te dwa kody.

Załóżmy, że potrzebujesz „front.css” bez „styles.css” na pierwszej stronie i „style.css” bez „front.css” na wszystkich innych stronach. Kod będzie wyglądał mniej więcej tak:

function mytheme_preprocess_page (&$variables)
{
  if (drupal_is_front_page()) {
    drupal_add_css(drupal_get_path('theme','mytheme'). '/css/front.css');
  } 
  else {
    drupal_add_css(drupal_get_path('theme','mytheme'). '/css/styles.css');
  }
}

function hook_css_alter(&$css) {
  if (drupal_is_front_page()) {
    unset($css[drupal_get_path('theme', 'mytheme') . '/css/styles.css']);
  }
  else {
    unset($css[drupal_get_path('theme', 'mytheme') . '/css/front.css']);
  } 
}

Również zamień „mytheme”.

Mam nadzieję, że będzie to pomocne.


Potrzebowałem ostatniego fragmentu kodu. I to działa, tj. Po usunięciu arkuszy stylów [wszystkie] [] = css / front.css z mojego theme.info - Chyba błędnie założyłem, że musimy to mieć wraz z arkuszami stylów [wszystkie] [] = css / styles .css Martwiłem się również, że ponieważ zastępuję page.tpl.php za pomocą page - front.tpl.php, to może nie działać, ale wszystko wygląda dobrze. To jest naprawdę pomocne. Dzięki!
Sd1,

Aby upewnić się, że wszyscy otrzymają to rozwiązanie; pamiętaj o usunięciu styles.css (domyślnie) i front.css z pliku theme.info. Opróżnij wszystkie skrzynki i powinno być dobrze.
Sd1,

1

Pominąłbym całkowicie dotykanie template.php i po prostu dodałem kolejny element w pliku .info twojego motywu

Powiedz, że masz arkusz stylów css/foo.css.

Tak wyglądałby Twój plik theme_name.info:

name = Theme Name
...
stylesheets[all][] = css/foo.css

W takim razie korzystasz z buforowania go za pomocą głównych arkuszy stylów, a ponieważ zakładam, że jest to dla twojej strony domowej, miałoby to sens.


I oczywiście musisz zakwalifikować selektory na podstawie atrybutów węzła, tj. Nid, typ węzła itp.
Alexander Hripak

Problem z tym podejściem polega na tym, że wpłynie to na wszystkie strony w witrynie z dodanym tutaj css
pal4life

1

Oprócz podejścia Drupal, gdy potrzebujesz tylko krótkiego fragmentu css wewnątrz swojego ciała HTML5, masz atrybut o zasięgu css. Zobacz https://stackoverflow.com/a/4607092/195812

To rozwiązanie pozwoli Ci uniknąć edytowania kodu i instalowania większej liczby modułów


0

Możesz wydrukować węzeł strony w znaczniku body

<body page-node-26419 ...>

Następnie możesz ograniczyć

body.page-node-26419 {
    background: red
}

Jest to przydatne w przypadku drobnych szybkich zmian


witamy w Drupal Answers! Ta odpowiedź została już podana powyżej przez Dave'a Reida.
Kojo
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.