wtorek, 19 maja 2015

[UPGRADE][Blogger] Robimy system kategorii cz.2 - dynamicznie generowane menu

TRUE
3865585716171268360
W tej części przygotujemy dynamiczne menu, taie jak widać tutaj, na górze strony. Będzie to wymagało kilka zabiegów i utworzenia paru funkcji, które automatycznie pobiorą nam informacje o kategoriach na stronie i policzą posty w nich zawarte. Konieczna będzie też mała modyfikacja szablonu w celu dodania do niego odpowiedzialnych za menu styli CSS.

DIV-a z naszym menu wklejamy w szablonie w miejsce tam, gdzie chcemy, aby nasze menu się wyświetliło, najlepiej przed znacznikiem </header>:

[code]
<div id='contact-links'>
    <div id='menu-container'>
        <nav id='neat-menu'></nav>    
        <div id='menu-search'>
          <form method='get' action='/search'>
                <input autocomplete='off' name='q' placeholder='szukaj...' type='text' value=''/>
            </form>
        </div>
    </div>
</div>
[/code]
Style CSS do menu zaczerpnięte zostały ze strony http://helplogger.blogspot.com/2014/02/add-a-neat-css-dropdown-menu-in-blogger.html, gdzie znajduje się prosty przykład użycia.
My jednak przebudujemy całość tak, aby zawartość naszego menu generowała się dynamicznie na podstawie zawartych w tablicach kategorii.

Style CSS wklejamy do naszego szablonu w bloku <skin>, ich pełny kod znajduje się poniżej.

Wymagane style CSS wklejamy tóż przed:
[code] ]]></b:skin> [/code]

w szablonie:
[code]
#contact-links {
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
    margin: auto;
    position: relative;
    width: 100%;
}
#contact-links a {
    color: #4C9FEB;
}
#contact-links a:hover {
    color: #3D85C6;
}
#my-links {
    float: right;
    font-size: 12px;
    margin: 4px 10px;
    overflow: hidden;
    text-shadow: 0 1px 0 #FFFFFF;
}
#my-links a {
    margin-left: 7px;
    padding-left: 8px;
    text-decoration: none;
}
#my-links a:first-child {
    border-width: 0;
}
#menu-container {
    background: -webkit-linear-gradient(#f6f6f6, #e9eaea) repeat scroll 0 0 transparent;
    background: -moz-linear-gradient(#f6f6f6, #e9eaea) repeat scroll 0 0 transparent;
    background: linear-gradient(#f6f6f6, #e9eaea) repeat scroll 0 0 transparent;
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f6f6f6', endColorstr='#e9eaea',GradientType=0 );
    border-radius: 0 0 4px 4px;
border:1px solid rgba(0,0,0,0.1);
    box-shadow: -1px 1px 0 rgba(255, 255, 255, 0.8) inset;
    clear: both;
    height: 46px;
    padding-top: 1px;
}
#neat-menu {
    float: left;
}
#neat-menu a {
    text-decoration: none;
}
#neat-menu ul {
    list-style: none;
    margin: 0;
    padding: 0;
}
#neat-menu > ul > li {
    float: left;
    padding-bottom: 12px;
}
#neat-menu ul li a {
    box-shadow: -1px 0 0 rgba(255, 255, 255, 0.8) inset, 1px 0 0 rgba(255, 255, 255, 0.8) inset;
    border-color: #D1D1D1;
    border-image: none;
    border-style: solid;
    border-width: 0 1px 0 0;
    color: #333333;
    display: block;
    font-size: 14px;
    height: 25px;
    line-height: 25px;
    padding: 11px 15px 10px;
    text-shadow: 0 1px 0 #FFFFFF;
}
#neat-menu ul li a:hover {
background: -webkit-linear-gradient(#efefef, #e9eaea) repeat scroll 0 0 transparent;
    background: -moz-linear-gradient(#efefef, #e9eaea) repeat scroll 0 0 transparent;
    background: linear-gradient(#efefef, #e9eaea) repeat scroll 0 0 transparent;
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#efefef', endColorstr='#e9eaea',GradientType=0 );
}
#neat-menu > ul > li.active > a {
    background: -webkit-linear-gradient(#55A6F1, #3F96E5) repeat scroll 0 0 transparent;
    background: -moz-linear-gradient(#55A6F1, #3F96E5) repeat scroll 0 0 transparent;
    background: linear-gradient(#55A6F1, #3F96E5) repeat scroll 0 0 transparent;
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#55A6F1', endColorstr='#3F96E5',GradientType=0 );
    border-bottom: 1px solid #2D81CC;
    border-top: 1px solid #4791D6;
    box-shadow: -1px 0 0 #55A6F1 inset, 1px 0 0 #55A6F1 inset;
    color: #FFFFFF;
    margin: -1px 0 -1px -1px;
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
}
#neat-menu > ul > li.active > a:hover {
    background: -webkit-linear-gradient(#499FEE, #3F96E5) repeat scroll 0 0 transparent;
    background: -moz-linear-gradient(#499FEE, #3F96E5) repeat scroll 0 0 transparent;
    background: linear-gradient(#499FEE, #3F96E5) repeat scroll 0 0 transparent;
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#499FEE', endColorstr='#3F96E5',GradientType=0 );
}
#neat-menu > ul > li:first-child > a {
    border-radius: 0 0 0 5px;
}
#neat-menu ul ul {
    background: -webkit-linear-gradient(#F7F7F7, #F4F4F4) repeat scroll 0 0 padding-box transparent;
    background: -moz-linear-gradient(#F7F7F7, #F4F4F4) repeat scroll 0 0 padding-box transparent;
    background: linear-gradient(#F7F7F7, #F4F4F4) repeat scroll 0 0 padding-box transparent;
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#F7F7F7', endColorstr='#F4F4F4',GradientType=0 );
    border-radius: 5px 5px 5px 5px;
    border: 1px solid rgba(0, 0, 0, 0.1);
    box-shadow: 0 1px 0 #FFFFFF inset;
    height: 0;
    margin-top: 1px;
    opacity: 0;
    overflow: hidden;
    width: 240px;
    padding: 0;
    position: absolute;
    visibility: hidden;
    z-index: 1;
    -webkit-transition: all .5s;
    -moz-transition: all .5s;
    -ms-transition: all .5s;
    -o-transition: all .5s;
    transition: all .5s;
}
#neat-menu ul li:hover ul  {
    margin-top: 0\2;
    height: auto;
    opacity: 1;
    visibility: visible;
}
#neat-menu ul ul a {
    border-right-width: 0;
    border-top: 1px solid #D1D1D1;
    box-shadow: 0 1px 0 #FFFFFF inset;
    color: #444444;
    height: 24px;
    line-height: 24px;
    padding: 7px 12px;
    text-shadow: 0 1px 0 #FFFFFF;
}
#neat-menu ul ul a:hover {
background: -webkit-linear-gradient(#55A6F1, #3F96E5) repeat scroll 0 0 transparent;
    background: -moz-linear-gradient(#55A6F1, #3F96E5) repeat scroll 0 0 transparent;
    background: linear-gradient(#55A6F1, #3F96E5) repeat scroll 0 0 transparent;
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#55A6F1', endColorstr='#3F96E5',GradientType=0 );
    border-top: 1px solid #4791D6;
    box-shadow: -1px 0 0 #55A6F1 inset, 1px 0 0 #55A6F1 inset;
    color: #FFFFFF;
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
}
#neat-menu ul ul li:first-child a {
    border-top-width: 0;
}
#menu-search {
    margin:8px 10px 0 0;
    float: right;
}
#menu-search form {
    background: url("https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdow_0Mws3c2PegbDq4HCqg3muPPI3OFccYCiFUS1pHSZgwGVo7_gNN7raVxpoc-ffbEMl9Cz9BMcVf2bcDtwOmY2529XNrDgQkyMsUUeXweNAsvLRohYYrCqdnxA6zgy-R_azzSeXdKHZ/s1600/menu-search.gif") no-repeat scroll 5% 50% transparent;
    border: 1px solid #CCCCCC;
    border-radius: 3px 3px 3px 3px;
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.05) inset, 0 1px 0 #FFFFFF;
    height: 26px;
    padding: 0 25px;
    position: relative;
    width: 130px;
}
#menu-search form:hover {
    background-color: #F9F9F9;
}
#menu-search form input {
    color: #999999;
    font-size: 13px;
    height: 26px;
    text-shadow: 0 1px 0 #FFFFFF;
    background: none repeat scroll 0 0 transparent;
    border: medium none;
    float: left;
    outline: medium none;
    padding: 0;
    width: 100%;
}
#menu-search form input.placeholder, #menu-search form input:-moz-placeholder {
    color: #C4C4C4;
}[/code]

Generujemy elementy menu

Przygotujemy teraz dynamiczne, rozwijane menu kategorii, które za pomocą jQuery podmienimy "w locie" w DIV-ie za menu odpowiedzialnym.

Popatrzmy na kod:
[code]
function renderSubCats(parentIndex)
{
 var subCatData = new Array();
 var str = '';

 for(subKey in subcategories)
 {
  subCatData = subcategories[subKey];
  if(subCatData[1] == parentIndex)
  {
   if(subKey == global_sublabel) {
    str = str.concat("<li class='active'><a class='active_sub' href='http://phpmajster.blogspot.com/search/label/" + subKey + "'><b>" + subCatData[2] + " (" + getCount(subKey) + ")</b></a></li>");
    $("li[subid='" + global_sublabel +"']").addClass('left_sub_active');
 
   } else {
    str = str.concat("<li><a href='http://phpmajster.blogspot.com/search/label/" + subKey + "'>" + subCatData[2] + " (" + getCount(subKey) + ")</a></li>");
   }
  }
 }
 if(str != '')
 {
  return '<ul>' + str + '</ul>';
 } else {

  return '';
 }
}[/code]

Przeanalizujmy go:
[code]
function renderSubCats(parentIndex)
{
 /*
 Na początek definiujemy startowe wartości dla zmiennych:
 subCatData - tymczasowa tablica do przechowywania danych etykiety,
 str - tymczasowa zmienna, która posłuży nam za przygotowanie kodu do wyświetlenia
 */

 var subCatData = new Array();
 var str = '';

 /*
 Przelecimy się teraz po tablicy subcategories[], czyli po wszystkich podkategoriach w niej zapisanych.
 Kluczem będzie tutaj NAZWA_ETYKIETY pobierana z tablicy.
 Najpierw pobieramy dane etykiety, po której w danej chwili leci nasza pętla i sprawdzamy, czy dana podkategoria należy do kategorii nadrzędnej, którą podaliśmy w parametrze, jeśli należy to lecimy dalej:
 */

 for(subKey in subcategories)
 {
  subCatData = subcategories[subKey];
  if(subCatData[1] == parentIndex)
  {
 
   /*
   Sprawdzamy, czy OBECNIE OGLĄDANA etykieta/podkategoria (zmienna global_sublabel) równa się obecnie przetwarzanego kluczowi w tablicy.
   Jeśli tak, dodajemy do elementu <li> klasę wyróżniającę element na liście - będzie pogrubiony klasą 'active':
   Dodatkowo - za pomocą jQuery wyróżniany też daną podkategorię w menu znajdującym się po lewej stronie.
   Robimy to za pomocą $("li[subid='" + global_sublabel +"']").addClass('left_sub_active');
   Jednocześnie każda z podkategorii jest w menu po lewej opisana jako:
   <li subid="NAZWA_ETYKIETY">TYTUŁ ETYKIETY</li>
 
   np.
 
   </li>
   <li subid='APACHE2_htaccess'><a href="http://phpmajster.blogspot.com/search/label/APACHE2_htaccess">Pliki .htaccess</a><script>writeCount('APACHE2_htaccess');</script>
   </li>

   Wygenerowany kod łączymy, domykamy znaczniki i tak przygotowany kod zwracamy do dalszego wyrenderowania na stronie.
   Jeśli kategoria jest pusta, nie otwieramy nowej listy podkategorii za pomocą <ul> i zwracamy pusty ciąg.
   */
 
   // my child
   if(subKey == global_sublabel) {
    str = str.concat("<li class='active'><a class='active_sub' href='http://phpmajster.blogspot.com/search/label/" + subKey + "'><b>" + subCatData[2] + " (" + getCount(subKey) + ")</b></a></li>");
    $("li[subid='" + global_sublabel +"']").addClass('left_sub_active');
 
   } else {
    str = str.concat("<li><a href='http://phpmajster.blogspot.com/search/label/" + subKey + "'>" + subCatData[2] + " (" + getCount(subKey) + ")</a></li>");
   }
  }
 }
 if(str != '')
 {
  return '<ul>' + str + '</ul>';
 } else {

  return '';
 }
}[/code]

Funkcja renderująca całość menu będzie miała nazwę renderMenu():
[code]
function renderMenu
{
 var pIndex = null;
 var str = '';
 var home_str = '<li class="active"><a href="/">Home</a></li>';

 for(key in categories)
 {
  if(global_label == key) {
   str = str.concat("<li class='active'><a href='http://phpmajster.blogspot.com/search/label/" + key + "'>" + categories[key][0] + "</a>");  
  } else {
   str = str.concat("<li><a href='http://phpmajster.blogspot.com/search/label/" + key + "'>" + categories[key][0] + "</a>");
  }

  str = str.concat(renderSubCats(pIndex));
  str = str.concat("</li>");
 }

 if(global_label != 'start')
 {
  home_str = '<li><a href="/">Home</a></li>';
 }

 return '<ul>' + home_str + str + '<li><a href="http://phpmajster.blogspot.com/p/autorkontakt.html">Redakcja</a></li></ul>';
}[/code]

Przeanalizujmy ją:
[code]
function renderMenu()
{
 /*
 Na początek definiujemy startowe wartości dla zmiennych:
 pIndex - przechowująca index w tablicy kategorii nadrzędnej,
 str - tymczasowa zmienna, która posłuży nam za przygotowanie kodu do wyświetlenia
 home_str - kod linku do strony startowej
 */

 var pIndex = null;
 var str = '';
 var home_str = '<li class="active"><a href="/">Home</a></li>';


 /*
 Przelecimy się teraz po tablicy categories[], czyli po wszystkich kategoriach w niej zapisanych.
 Kluczem będzie tutaj NAZWA_ETYKIETY pobierana z tablicy.
 Warto zauważyć, że w zmiennej global_label znajduje się pobrana NAZWA ETYKIETY obecnie oglądanego posta, lub postów.
 */

 for(key in categories)
 {
  /*
  Na podstawie NAZWY_ETYKIETY kategorii pobieramy jej index w tablicy za pomocą funkcji getCatIndex():
  */
  pIndex = getCatIndex(key);


  /*
  Sprawdzamy, czy OBECNIE OGLĄDANA etykieta (zmienna global_label) równa się obecnie przetwarzanego kluczowi w tablicy.
  Jeśli tak, dodajemy do elementu <li> klasę wyróżniającę element na liście - będzie pogrubiony klasą 'active':
  */
  if(global_label == key) {
   str = str.concat("<li class='active'><a href='http://phpmajster.blogspot.com/search/label/" + key + "'>" + categories[key][0] + "</a>");  
  } else {
   str = str.concat("<li><a href='http://phpmajster.blogspot.com/search/label/" + key + "'>" + categories[key][0] + "</a>");
  }

  /*
  Po utworzeniu kodu elementu <li> kategorii nadrzędnej, czas na wyrenderowanie jej podkategorii.
  Wykorzystamy do tego funkcję renderSubCats(), która renderuje menu podkategorii dla kategorii o indexie pobieranym jako parametr.
  Po pobraniu kodu podkategorii dołączamy wygenerowany kod tutaj, domykamy listę znacznikiem </li> i lecimy po następnym elemencie tablicy:
  */

  str = str.concat(renderSubCats(pIndex));
  str = str.concat("</li>");
 }

 /*
 Jeśli nie znajdujemy się na stronie głównej, to nie dodajemy do elementu listy odpowiedzialnej za link do strony strartowej klasy wyróżniającej.
 Robimy to za pomocą sprawdzenia, czy globalna zmienna global_label, w ktorej znajduje się pobrana wartość obecnie wyświetlanej etykiety równa się 'start':
 */
 if(global_label != 'start')
 {
  home_str = '<li><a href="/">Home</a></li>';
 }

 /*
 Na koniec składamy wszystko całość i zwracamy gotowy kod menu do wyświetlenia na stronie.
 */
 return '<ul>' + home_str + str + '<li><a href="http://phpmajster.blogspot.com/p/autorkontakt.html">Redakcja</a></li></ul>';
}[/code]

Brak komentarzy:

Prześlij komentarz

Masz sugestię? Znalazłeś błąd? Napisz komentarz! :)

webmaester.pl - profesjonalne projektowanie WWW i webaplikacji
webmaester.pl - profesjonalne projektowanie WWW i webaplikacji