2009-06-21 7 views
7

Mam szablon base.html, który zawiera listę łączy.Django: Czy jest lepszy sposób na pogrubienie bieżącego łącza strony

Przykład:

<div id="sidebar1"> 
     <ul> 
     <li><a href="/" title="">Index</a></li> 
     <li><a href="/stuff/" title="" class="current">Stuff</a></li> 
     <li><a href="/about/" title="">About Me</a></li> 
     <li><a href="/contact/" title="">Contact Me</a></li> 
    </div> 

Następnie mam w views.py definicję każdej z index.html, stuff.html, about.html i contact.html. Każdy z tych szablonów pochodzi po prostu z szablonu base.html i ustawia własne tytuły i treści.

Moje pytanie dotyczy powyższego/rzeczy, które mam class = "current".

Chciałbym, aby bieżąca strona, na której się znajduję, miała ten atrybut klasy.

Mogę ustawić inną zmienną w każdym widoku, np. Current_page = "about", a następnie porównać w szablonie z {% ifequal %} w każdym elemencie klasy każdego linku, ale to wydaje się duplikowaniem pracy (z powodu dodatkowej zmiennej widoku).

Czy istnieje lepszy sposób? Może, jeśli istnieje sposób na uzyskanie nazwy funkcji widoku, z której szablon został automatycznie wypełniony, nie musiałbym ustawiać dodatkowej zmiennej? Wydaje się również, że jest dużo nierówności.

Odpowiedz

16

Oto elegancki sposób robienia tego, który skądś skopiowałem i żałuję tylko, że nie pamiętam gdzie, więc mogłem dać im kredyt. 8-)

I przypisać id do każdego z moich stron (lub wszystkich stron w sekcji) tak:

In index.html: <body id='section-intro'>... 
In faq.html:  <body id='section-faq'>... 
In download.html: <body id='section-download'>... 

a potem id dla odpowiednich linków:

<li id='nav-intro'><a href="./">Introduction</a></li> 
<li id='nav-faq'><a href="./faq.html">FAQ</a></li> 
<li id='nav-download'><a href="./download.html">Download</a></li> 

I w CSS ustawiam regułę:

#section-intro #nav-intro, 
#section-faq #nav-faq, 
#section-download #nav-download { 
    font-weight: bold; 
    /* And whatever other styles the current link should have. */ 
} 

To wszystko działa w sposób deklaratywny w celu kontrolowania stylu linku, do którego należy aktualna strona. Możesz go zobaczyć w akcji tutaj: http://entrian.com/source-search/

Po skonfigurowaniu jest to bardzo prosty i prosty system, ponieważ:

  • nie trzeba zadzierać z szablonu o znacznikach w linkach
  • nie kończy się przy użyciu duży brzydki switch oświadczenia lub if/else/else oświadczenia
  • Dodawanie stron do sekcji prostu działa [TM]
  • Zmiana sposobu, w jaki rzeczy wyglądają zawsze, oznacza zmianę CSS, a nie znaczników.

Nie używam Django, ale ten system działa wszędzie. W twoim przypadku, gdy "ustawiasz własne tytuły i zawartość", musisz także ustawić wartość body id i nie trzeba już stosować żadnych innych znaczników Django.

Pomysł ten łatwo można rozszerzyć także na inne sytuacje, np. "Chcę link do pobrania na pasku bocznym na każdej stronie, oprócz samych stron pobierania."Można to zrobić w CSS tak:

#section-download #sidebar #download-link { 
    display: none; 
} 

zamiast umieścić warunkową szablonu znaczników w HTML bocznego

+0

Nie oznacza to dużo powielonych treści w CSS chociaż? –

+0

... Mam na myśli styl dla każdego identyfikatora linku. –

+0

To jedna linia CSS dla każdej strony/sekcji. Sam styl pojawia się tylko raz, z rozdzieloną przecinkami listą par sekcji/nav przed nią. – RichieHindle

2

nie używali Django, ale mam do czynienia z tym samym numerze w. Kohana (PHP) i Rails

Co zrobić w Kohana.

<li><a href="/admin/dashboard" <?= (get_class($this) == 'Dashboard_Controller') ? "class=\"active\"" : NULL ?>>Dashboard</a></li> 
<li><a href="/admin/campaigns" <?= (get_class($this) == 'Campaigns_Controller') ? "class=\"active\"" : NULL ?>>Campaigns</a></li> 
<li><a href="/admin/lists" <?= (get_class($this) == 'Lists_Controller') ? "class=\"active\"" : NULL ?>>Lists</a></li> 

Co zrobić w Rails:

<li><a href="/main" <%= 'class="active"' if (controller.controller_name == 'main') %>>Overview</a></li> 
<li><a href="/notifications" <%= 'class="active"' if (controller.controller_name == 'notifications') %>>Notifications</a></li> 
<li><a href="/reports" <%= 'class="active"' if (controller.controller_name == 'reports') %>>Reports</a></li> 
1

widzę tylko kilka sposobów robi, unikając powtarzających ifequals:

  1. Javascript. Coś wzdłuż linii (jQuery):

    var parts = window.location.pathname.split('/'); 
    var page = parts[parts.length-1]; 
    $('#sidebar1 a[href*=' + page + ']').addClass('current'); 
    
  2. Zmień swoje poglądy zawiera listę stron z nimi powiązanymi tytułów i adresów URL i utworzyć {% for%} pętlę w szablonie, który przejdzie przez to listę i dodaj pojedynczy {% ifequal%}.

Opcja 2 jest ulubionym miejscem, w którym stoję. Jeśli logika wszystkich stron jest taka sama, a tylko szablony różnią się, możesz rozważyć użycie modelu FlatPages dla każdej ze stron. Jeśli logika jest inna i potrzebujesz różnych modeli, możesz rozważyć użycie jakiejś aplikacji do obsługi menu. Bezwstydna: Mam menuing app of my own

1

Jeśli dodać procesor request kontekstowe, to całkiem proste:

settings.py: 

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.request', 
    'django.contrib.auth.context_processors.auth' # admin app wants this too 
) 

Teraz masz dostęp do HttpRequest, który zawiera ścieżkę żądania. Podkreślając bieżąca strona jest prosta sprawa sprawdzenie czy ścieżka pasuje cel tego linku, to znaczy, że jesteś już istnieje:

<li><a class="{% if request.path == '/' %}current{% endif %}" href="/">Index</a></li> 
<li><a class="{% if request.path == '/stuff/' %}current{% endif %}" href="/stuff/">Stuff</a></li> 
<li><a class="{% if request.path == '/about/' %}current{% endif %}" href="/about/">About Me</a></li> 
<li><a class="{% if request.path == '/contact/' %}current{% endif %}" href="/contact/">Contact Me</a></li> 
Powiązane problemy