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>:


  1. <div id='contact-links'>
  2.  
  3.     <div id='menu-container'>
  4.  
  5.         <nav id='neat-menu'></nav>    
  6.  
  7.         <div id='menu-search'>
  8.  
  9.           <form method='get' action='/search'>
  10.  
  11.                 <input autocomplete='off' name='q' placeholder='szukaj...' type='text' value=''/>
  12.  
  13.             </form>
  14.  
  15.         </div>
  16.  
  17.     </div>
  18.  
  19. </div>
  20.  

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:

  1. ]]></b:skin>


w szablonie:

  1. #contact-links {
  2.  
  3.     text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
  4.  
  5.     margin: auto;
  6.  
  7.     position: relative;
  8.  
  9.     width: 100%;
  10.  
  11. }
  12.  
  13. #contact-links a {
  14.  
  15.     color: #4C9FEB;
  16.  
  17. }
  18.  
  19. #contact-links a:hover {
  20.  
  21.     color: #3D85C6;
  22.  
  23. }
  24.  
  25. #my-links {
  26.  
  27.     float: right;
  28.  
  29.     font-size: 12px;
  30.  
  31.     margin: 4px 10px;
  32.  
  33.     overflow: hidden;
  34.  
  35.     text-shadow: 0 1px 0 #FFFFFF;
  36.  
  37. }
  38.  
  39. #my-links a {
  40.  
  41.     margin-left: 7px;
  42.  
  43.     padding-left: 8px;
  44.  
  45.     text-decoration: none;
  46.  
  47. }
  48.  
  49. #my-links a:first-child {
  50.  
  51.     border-width: 0;
  52.  
  53. }
  54.  
  55. #menu-container {
  56.  
  57.     background: -webkit-linear-gradient(#f6f6f6, #e9eaea) repeat scroll 0 0 transparent;
  58.  
  59.     background: -moz-linear-gradient(#f6f6f6, #e9eaea) repeat scroll 0 0 transparent;
  60.  
  61.     background: linear-gradient(#f6f6f6, #e9eaea) repeat scroll 0 0 transparent;
  62.  
  63.     filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f6f6f6', endColorstr='#e9eaea',GradientType=0 );
  64.  
  65.     border-radius: 0 0 4px 4px;
  66.  
  67. border:1px solid rgba(0,0,0,0.1);
  68.  
  69.     box-shadow: -1px 1px 0 rgba(255, 255, 255, 0.8) inset;
  70.  
  71.     clear: both;
  72.  
  73.     height: 46px;
  74.  
  75.     padding-top: 1px;
  76.  
  77. }
  78.  
  79. #neat-menu {
  80.  
  81.     float: left;
  82.  
  83. }
  84.  
  85. #neat-menu a {
  86.  
  87.     text-decoration: none;
  88.  
  89. }
  90.  
  91. #neat-menu ul {
  92.  
  93.     list-style: none;
  94.  
  95.     margin: 0;
  96.  
  97.     padding: 0;
  98.  
  99. }
  100.  
  101. #neat-menu > ul > li {
  102.  
  103.     float: left;
  104.  
  105.     padding-bottom: 12px;
  106.  
  107. }
  108.  
  109. #neat-menu ul li a {
  110.  
  111.     box-shadow: -1px 0 0 rgba(255, 255, 255, 0.8) inset, 1px 0 0 rgba(255, 255, 255, 0.8) inset;
  112.  
  113.     border-color: #D1D1D1;
  114.  
  115.     border-image: none;
  116.  
  117.     border-style: solid;
  118.  
  119.     border-width: 0 1px 0 0;
  120.  
  121.     color: #333333;
  122.  
  123.     display: block;
  124.  
  125.     font-size: 14px;
  126.  
  127.     height: 25px;
  128.  
  129.     line-height: 25px;
  130.  
  131.     padding: 11px 15px 10px;
  132.  
  133.     text-shadow: 0 1px 0 #FFFFFF;
  134.  
  135. }
  136.  
  137. #neat-menu ul li a:hover {
  138.  
  139. background: -webkit-linear-gradient(#efefef, #e9eaea) repeat scroll 0 0 transparent;
  140.  
  141.     background: -moz-linear-gradient(#efefef, #e9eaea) repeat scroll 0 0 transparent;
  142.  
  143.     background: linear-gradient(#efefef, #e9eaea) repeat scroll 0 0 transparent;
  144.  
  145.     filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#efefef', endColorstr='#e9eaea',GradientType=0 );
  146.  
  147. }
  148.  
  149. #neat-menu > ul > li.active > a {
  150.  
  151.     background: -webkit-linear-gradient(#55A6F1, #3F96E5) repeat scroll 0 0 transparent;
  152.  
  153.     background: -moz-linear-gradient(#55A6F1, #3F96E5) repeat scroll 0 0 transparent;
  154.  
  155.     background: linear-gradient(#55A6F1, #3F96E5) repeat scroll 0 0 transparent;
  156.  
  157.     filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#55A6F1', endColorstr='#3F96E5',GradientType=0 );
  158.  
  159.     border-bottom: 1px solid #2D81CC;
  160.  
  161.     border-top: 1px solid #4791D6;
  162.  
  163.     box-shadow: -1px 0 0 #55A6F1 inset, 1px 0 0 #55A6F1 inset;
  164.  
  165.     color: #FFFFFF;
  166.  
  167.     margin: -1px 0 -1px -1px;
  168.  
  169.     text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
  170.  
  171. }
  172.  
  173. #neat-menu > ul > li.active > a:hover {
  174.  
  175.     background: -webkit-linear-gradient(#499FEE, #3F96E5) repeat scroll 0 0 transparent;
  176.  
  177.     background: -moz-linear-gradient(#499FEE, #3F96E5) repeat scroll 0 0 transparent;
  178.  
  179.     background: linear-gradient(#499FEE, #3F96E5) repeat scroll 0 0 transparent;
  180.  
  181.     filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#499FEE', endColorstr='#3F96E5',GradientType=0 );
  182.  
  183. }
  184.  
  185. #neat-menu > ul > li:first-child > a {
  186.  
  187.     border-radius: 0 0 0 5px;
  188.  
  189. }
  190.  
  191. #neat-menu ul ul {
  192.  
  193.     background: -webkit-linear-gradient(#F7F7F7, #F4F4F4) repeat scroll 0 0 padding-box transparent;
  194.  
  195.     background: -moz-linear-gradient(#F7F7F7, #F4F4F4) repeat scroll 0 0 padding-box transparent;
  196.  
  197.     background: linear-gradient(#F7F7F7, #F4F4F4) repeat scroll 0 0 padding-box transparent;
  198.  
  199.     filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#F7F7F7', endColorstr='#F4F4F4',GradientType=0 );
  200.  
  201.     border-radius: 5px 5px 5px 5px;
  202.  
  203.     border: 1px solid rgba(0, 0, 0, 0.1);
  204.  
  205.     box-shadow: 0 1px 0 #FFFFFF inset;
  206.  
  207.     height: 0;
  208.  
  209.     margin-top: 1px;
  210.  
  211.     opacity: 0;
  212.  
  213.     overflow: hidden;
  214.  
  215.     width: 240px;
  216.  
  217.     padding: 0;
  218.  
  219.     position: absolute;
  220.  
  221.     visibility: hidden;
  222.  
  223.     z-index: 1;
  224.  
  225.     -webkit-transition: all .5s;
  226.  
  227.     -moz-transition: all .5s;
  228.  
  229.     -ms-transition: all .5s;
  230.  
  231.     -o-transition: all .5s;
  232.  
  233.     transition: all .5s;
  234.  
  235. }
  236.  
  237. #neat-menu ul li:hover ul  {
  238.  
  239.     margin-top: 0\2;
  240.  
  241.     height: auto;
  242.  
  243.     opacity: 1;
  244.  
  245.     visibility: visible;
  246.  
  247. }
  248.  
  249. #neat-menu ul ul a {
  250.  
  251.     border-right-width: 0;
  252.  
  253.     border-top: 1px solid #D1D1D1;
  254.  
  255.     box-shadow: 0 1px 0 #FFFFFF inset;
  256.  
  257.     color: #444444;
  258.  
  259.     height: 24px;
  260.  
  261.     line-height: 24px;
  262.  
  263.     padding: 7px 12px;
  264.  
  265.     text-shadow: 0 1px 0 #FFFFFF;
  266.  
  267. }
  268.  
  269. #neat-menu ul ul a:hover {
  270.  
  271. background: -webkit-linear-gradient(#55A6F1, #3F96E5) repeat scroll 0 0 transparent;
  272.  
  273.     background: -moz-linear-gradient(#55A6F1, #3F96E5) repeat scroll 0 0 transparent;
  274.  
  275.     background: linear-gradient(#55A6F1, #3F96E5) repeat scroll 0 0 transparent;
  276.  
  277.     filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#55A6F1', endColorstr='#3F96E5',GradientType=0 );
  278.  
  279.     border-top: 1px solid #4791D6;
  280.  
  281.     box-shadow: -1px 0 0 #55A6F1 inset, 1px 0 0 #55A6F1 inset;
  282.  
  283.     color: #FFFFFF;
  284.  
  285.     text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
  286.  
  287. }
  288.  
  289. #neat-menu ul ul li:first-child a {
  290.  
  291.     border-top-width: 0;
  292.  
  293. }
  294.  
  295. #menu-search {
  296.  
  297.     margin:8px 10px 0 0;
  298.  
  299.     float: right;
  300.  
  301. }
  302.  
  303. #menu-search form {
  304.  
  305.     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;
  306.  
  307.     border: 1px solid #CCCCCC;
  308.  
  309.     border-radius: 3px 3px 3px 3px;
  310.  
  311.     box-shadow: 0 1px 0 rgba(0, 0, 0, 0.05) inset, 0 1px 0 #FFFFFF;
  312.  
  313.     height: 26px;
  314.  
  315.     padding: 0 25px;
  316.  
  317.     position: relative;
  318.  
  319.     width: 130px;
  320.  
  321. }
  322.  
  323. #menu-search form:hover {
  324.  
  325.     background-color: #F9F9F9;
  326.  
  327. }
  328.  
  329. #menu-search form input {
  330.  
  331.     color: #999999;
  332.  
  333.     font-size: 13px;
  334.  
  335.     height: 26px;
  336.  
  337.     text-shadow: 0 1px 0 #FFFFFF;
  338.  
  339.     background: none repeat scroll 0 0 transparent;
  340.  
  341.     border: medium none;
  342.  
  343.     float: left;
  344.  
  345.     outline: medium none;
  346.  
  347.     padding: 0;
  348.  
  349.     width: 100%;
  350.  
  351. }
  352.  
  353. #menu-search form input.placeholder, #menu-search form input:-moz-placeholder {
  354.  
  355.     color: #C4C4C4;
  356.  
  357. }


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:

  1. function renderSubCats(parentIndex)
  2.  
  3. {
  4.  
  5.  var subCatData = new Array();
  6.  
  7.  var str = '';
  8.  
  9.  
  10.  
  11.  for(subKey in subcategories)
  12.  
  13.  {
  14.  
  15.   subCatData = subcategories[subKey];
  16.  
  17.   if(subCatData[1] == parentIndex)
  18.  
  19.   {
  20.  
  21.    if(subKey == global_sublabel) {
  22.  
  23.     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>");
  24.  
  25.     $("li[subid='" + global_sublabel +"']").addClass('left_sub_active');
  26.  
  27.  
  28.  
  29.    } else {
  30.  
  31.     str = str.concat("<li><a href='http://phpmajster.blogspot.com/search/label/" + subKey + "'>" + subCatData[2] + " (" + getCount(subKey) + ")</a></li>");
  32.  
  33.    }
  34.  
  35.   }
  36.  
  37.  }
  38.  
  39.  if(str != '')
  40.  
  41.  {
  42.  
  43.   return '<ul>' + str + '</ul>';
  44.  
  45.  } else {
  46.  
  47.  
  48.  
  49.   return '';
  50.  
  51.  }
  52.  
  53. }


Przeanalizujmy go:

  1. function renderSubCats(parentIndex)
  2.  
  3. {
  4.  
  5.  /*
  6.  
  7.  Na początek definiujemy startowe wartości dla zmiennych:
  8.  
  9.  subCatData - tymczasowa tablica do przechowywania danych etykiety,
  10.  
  11.  str - tymczasowa zmienna, która posłuży nam za przygotowanie kodu do wyświetlenia
  12.  
  13.  */
  14.  
  15.  
  16.  
  17.  var subCatData = new Array();
  18.  
  19.  var str = '';
  20.  
  21.  
  22.  
  23.  /*
  24.  
  25.  Przelecimy się teraz po tablicy subcategories[], czyli po wszystkich podkategoriach w niej zapisanych.
  26.  
  27.  Kluczem będzie tutaj NAZWA_ETYKIETY pobierana z tablicy.
  28.  
  29.  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:
  30.  
  31.  */
  32.  
  33.  
  34.  
  35.  for(subKey in subcategories)
  36.  
  37.  {
  38.  
  39.   subCatData = subcategories[subKey];
  40.  
  41.   if(subCatData[1] == parentIndex)
  42.  
  43.   {
  44.  
  45.  
  46.  
  47.    /*
  48.  
  49.    Sprawdzamy, czy OBECNIE OGLĄDANA etykieta/podkategoria (zmienna global_sublabel) równa się obecnie przetwarzanego kluczowi w tablicy.
  50.  
  51.    Jeśli tak, dodajemy do elementu <li> klasę wyróżniającę element na liście - będzie pogrubiony klasą 'active':
  52.  
  53.    Dodatkowo - za pomocą jQuery wyróżniany też daną podkategorię w menu znajdującym się po lewej stronie.
  54.  
  55.    Robimy to za pomocą $("li[subid='" + global_sublabel +"']").addClass('left_sub_active');
  56.  
  57.    Jednocześnie każda z podkategorii jest w menu po lewej opisana jako:
  58.  
  59.    <li subid="NAZWA_ETYKIETY">TYTUŁ ETYKIETY</li>
  60.  
  61.  
  62.  
  63.    np.
  64.  
  65.  
  66.  
  67.    </li>
  68.  
  69.    <li subid='APACHE2_htaccess'><a href="http://phpmajster.blogspot.com/search/label/APACHE2_htaccess">Pliki .htaccess</a><script>writeCount('APACHE2_htaccess');</script>
  70.  
  71.    </li>
  72.  
  73.  
  74.  
  75.    Wygenerowany kod łączymy, domykamy znaczniki i tak przygotowany kod zwracamy do dalszego wyrenderowania na stronie.
  76.  
  77.    Jeśli kategoria jest pusta, nie otwieramy nowej listy podkategorii za pomocą <ul> i zwracamy pusty ciąg.
  78.  
  79.    */
  80.  
  81.  
  82.  
  83.    // my child
  84.  
  85.    if(subKey == global_sublabel) {
  86.  
  87.     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>");
  88.  
  89.     $("li[subid='" + global_sublabel +"']").addClass('left_sub_active');
  90.  
  91.  
  92.  
  93.    } else {
  94.  
  95.     str = str.concat("<li><a href='http://phpmajster.blogspot.com/search/label/" + subKey + "'>" + subCatData[2] + " (" + getCount(subKey) + ")</a></li>");
  96.  
  97.    }
  98.  
  99.   }
  100.  
  101.  }
  102.  
  103.  if(str != '')
  104.  
  105.  {
  106.  
  107.   return '<ul>' + str + '</ul>';
  108.  
  109.  } else {
  110.  
  111.  
  112.  
  113.   return '';
  114.  
  115.  }
  116.  
  117. }


Funkcja renderująca całość menu będzie miała nazwę renderMenu():

  1. function renderMenu
  2.  
  3. {
  4.  
  5.  var pIndex = null;
  6.  
  7.  var str = '';
  8.  
  9.  var home_str = '<li class="active"><a href="/">Home</a></li>';
  10.  
  11.  
  12.  
  13.  for(key in categories)
  14.  
  15.  {
  16.  
  17.   if(global_label == key) {
  18.  
  19.    str = str.concat("<li class='active'><a href='http://phpmajster.blogspot.com/search/label/" + key + "'>" + categories[key][0] + "</a>");  
  20.  
  21.   } else {
  22.  
  23.    str = str.concat("<li><a href='http://phpmajster.blogspot.com/search/label/" + key + "'>" + categories[key][0] + "</a>");
  24.  
  25.   }
  26.  
  27.  
  28.  
  29.   str = str.concat(renderSubCats(pIndex));
  30.  
  31.   str = str.concat("</li>");
  32.  
  33.  }
  34.  
  35.  
  36.  
  37.  if(global_label != 'start')
  38.  
  39.  {
  40.  
  41.   home_str = '<li><a href="/">Home</a></li>';
  42.  
  43.  }
  44.  
  45.  
  46.  
  47.  return '<ul>' + home_str + str + '<li><a href="http://phpmajster.blogspot.com/p/autorkontakt.html">Redakcja</a></li></ul>';
  48.  
  49. }


Przeanalizujmy ją:

  1. function renderMenu()
  2.  
  3. {
  4.  
  5.  /*
  6.  
  7.  Na początek definiujemy startowe wartości dla zmiennych:
  8.  
  9.  pIndex - przechowująca index w tablicy kategorii nadrzędnej,
  10.  
  11.  str - tymczasowa zmienna, która posłuży nam za przygotowanie kodu do wyświetlenia
  12.  
  13.  home_str - kod linku do strony startowej
  14.  
  15.  */
  16.  
  17.  
  18.  
  19.  var pIndex = null;
  20.  
  21.  var str = '';
  22.  
  23.  var home_str = '<li class="active"><a href="/">Home</a></li>';
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  /*
  30.  
  31.  Przelecimy się teraz po tablicy categories[], czyli po wszystkich kategoriach w niej zapisanych.
  32.  
  33.  Kluczem będzie tutaj NAZWA_ETYKIETY pobierana z tablicy.
  34.  
  35.  Warto zauważyć, że w zmiennej global_label znajduje się pobrana NAZWA ETYKIETY obecnie oglądanego posta, lub postów.
  36.  
  37.  */
  38.  
  39.  
  40.  
  41.  for(key in categories)
  42.  
  43.  {
  44.  
  45.   /*
  46.  
  47.   Na podstawie NAZWY_ETYKIETY kategorii pobieramy jej index w tablicy za pomocą funkcji getCatIndex():
  48.  
  49.   */
  50.  
  51.   pIndex = getCatIndex(key);
  52.  
  53.  
  54.  
  55.  
  56.  
  57.   /*
  58.  
  59.   Sprawdzamy, czy OBECNIE OGLĄDANA etykieta (zmienna global_label) równa się obecnie przetwarzanego kluczowi w tablicy.
  60.  
  61.   Jeśli tak, dodajemy do elementu <li> klasę wyróżniającę element na liście - będzie pogrubiony klasą 'active':
  62.  
  63.   */
  64.  
  65.   if(global_label == key) {
  66.  
  67.    str = str.concat("<li class='active'><a href='http://phpmajster.blogspot.com/search/label/" + key + "'>" + categories[key][0] + "</a>");  
  68.  
  69.   } else {
  70.  
  71.    str = str.concat("<li><a href='http://phpmajster.blogspot.com/search/label/" + key + "'>" + categories[key][0] + "</a>");
  72.  
  73.   }
  74.  
  75.  
  76.  
  77.   /*
  78.  
  79.   Po utworzeniu kodu elementu <li> kategorii nadrzędnej, czas na wyrenderowanie jej podkategorii.
  80.  
  81.   Wykorzystamy do tego funkcję renderSubCats(), która renderuje menu podkategorii dla kategorii o indexie pobieranym jako parametr.
  82.  
  83.   Po pobraniu kodu podkategorii dołączamy wygenerowany kod tutaj, domykamy listę znacznikiem </li> i lecimy po następnym elemencie tablicy:
  84.  
  85.   */
  86.  
  87.  
  88.  
  89.   str = str.concat(renderSubCats(pIndex));
  90.  
  91.   str = str.concat("</li>");
  92.  
  93.  }
  94.  
  95.  
  96.  
  97.  /*
  98.  
  99.  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.
  100.  
  101.  Robimy to za pomocą sprawdzenia, czy globalna zmienna global_label, w ktorej znajduje się pobrana wartość obecnie wyświetlanej etykiety równa się 'start':
  102.  
  103.  */
  104.  
  105.  if(global_label != 'start')
  106.  
  107.  {
  108.  
  109.   home_str = '<li><a href="/">Home</a></li>';
  110.  
  111.  }
  112.  
  113.  
  114.  
  115.  /*
  116.  
  117.  Na koniec składamy wszystko całość i zwracamy gotowy kod menu do wyświetlenia na stronie.
  118.  
  119.  */
  120.  
  121.  return '<ul>' + home_str + str + '<li><a href="http://phpmajster.blogspot.com/p/autorkontakt.html">Redakcja</a></li></ul>';
  122.  
  123. }

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