{"id":13715,"date":"2026-05-04T08:00:00","date_gmt":"2026-05-04T06:00:00","guid":{"rendered":"https:\/\/eugigufo.net\/it\/?page_id=13715"},"modified":"2026-04-23T13:44:49","modified_gmt":"2026-04-23T11:44:49","slug":"paragrafo42","status":"publish","type":"page","link":"https:\/\/eugigufo.net\/it\/inerario\/paragrafo42\/","title":{"rendered":"\u00a7 42. Il calendario annuale per WordPress"},"content":{"rendered":"<p>Da&nbsp;tempo volevo realizzare sul sito una cosa del genere: un&nbsp;calendario annuale (sia dell&rsquo;anno corrente sia di&nbsp;ciascuno degli anni passati) in&nbsp;cui, per ogni data, ci&nbsp;sia un&nbsp;link che rimandi a&nbsp;una raccolta dei post del blog pubblicati proprio in&nbsp;quel giorno (se&nbsp;effettivamente &egrave;&nbsp;stato pubblicato qualcosa). In&nbsp;LiveJournal (e&nbsp;altre piattaforme di&nbsp;blogging) un&nbsp;calendario del genere esisteva ed&nbsp;era molto comodo come strumento per cercare vecchi articoli e\/o per analizzare l&rsquo;attivit&agrave; del blog (proprio o&nbsp;altrui). In&nbsp;WordPress, invece, un&nbsp;calendario cos&igrave; non c&rsquo;&egrave; e, se&nbsp;ricordo bene, non c&rsquo;&egrave; mai stato (o&nbsp;magari esisteva talmente tanto tempo fa&nbsp;che me&nbsp;ne&nbsp;sono completamente dimenticato): c&rsquo;&egrave; solo un&nbsp;calendario analogo basato sui singoli mesi, che per&ograve; risulta decisamente scomodo per la&nbsp;maggior parte delle ricerche e&nbsp;delle analisi.<br \/>\nPer realizzare una cosa del genere con le&nbsp;forze proprie mi&nbsp;serviva un&nbsp;po&rsquo; di&nbsp;tempo libero: finalmente sono riuscito a&nbsp;trovarlo! Ancora pi&ugrave; importante (e&nbsp;interessante) &egrave;&nbsp;il&nbsp;fatto che questo tempo non &egrave;&nbsp;stato sprecato: sono riuscito a&nbsp;creare il&nbsp;calendario-archivio. Un&nbsp;esempio funzionante &egrave;&nbsp;disponibile <a href=\"https:\/\/eugigufo.net\/it\/blog\/archives\/calendario\/\">sotto il&nbsp;link<\/a>, mentre in&nbsp;questo articolo descriver&ograve; a&nbsp;parole tutte le&nbsp;caratteristiche del mio calendario e&nbsp;fornir&ograve; i&nbsp;codici base in&nbsp;PHP e&nbsp;CSS.<br \/>\nLe&nbsp;caratteristiche del mio calendario annuale del blog per WordPress:<br \/>\n&ndash;&nbsp;calendario completo dell&rsquo;anno (sono visibili tutti i&nbsp;12&nbsp;mesi, indipendentemente dalla data corrente al&nbsp;momento della consultazione);<br \/>\n&ndash;&nbsp;possibilit&agrave; di&nbsp;visualizzare gli anni passati (ma&nbsp;non precedenti all&rsquo;anno del primo post pubblico del blog);<br \/>\n&ndash;&nbsp;i&nbsp;giorni con post pubblici vengono automaticamente trasformati in&nbsp;link che rimandano alle rispettive date nell&rsquo;archivio degli articoli;<br \/>\n&ndash;&nbsp;al&nbsp;passaggio del cursore su&nbsp;un&nbsp;giorno con link compare un&nbsp;suggerimento con il&nbsp;numero di&nbsp;post pubblicati in&nbsp;quella data;<br \/>\n&ndash;&nbsp;nei calendari degli anni passati, la&nbsp;data corrente (&laquo;oggi&raquo;) &egrave;&nbsp;evidenziata con una cornice ben visibile;<br \/>\n&ndash;&nbsp;le&nbsp;celle corrispondenti ai&nbsp;giorni in&nbsp;cui &egrave;&nbsp;stato pubblicato almeno un&nbsp;post cambiano il&nbsp;colore di&nbsp;sfondo;<br \/>\n&ndash;&nbsp;il&nbsp;calendario ha&nbsp;un&nbsp;design responsive: su&nbsp;schermi grandi e&nbsp;medi viene mostrata una griglia di&nbsp;3&times;4&nbsp;mesi, mentre su&nbsp;schermi piccoli i&nbsp;mesi dell&rsquo;anno sono disposti in&nbsp;colonna;<br \/>\n&ndash;&nbsp;le&nbsp;query al&nbsp;database sono ottimizzate in&nbsp;modo tale che il&nbsp;calendario non sia lento a&nbsp;caricarsi nemmeno nei blog con decine di&nbsp;migliaia di&nbsp;articoli.<br \/>\nEd&nbsp;ecco che ora passiamo ai&nbsp;codici del calendario (spero che tu&nbsp;abbia letto tutto il&nbsp;testo qui sopra: pu&ograve; aiutarti a&nbsp;orientarti meglio).<br \/>\nIl&nbsp;codice PHP, che pu&ograve; essere testato direttamente cos&igrave; com&rsquo;&egrave;: basta copiarlo e&nbsp;incollarlo nel layout della tua pagina:<\/p>\n<pre class=\"brush: php; collapse: false; title: listing 1; notranslate\" title=\"listing 1\">\n&lt;?php\nglobal $wpdb;\n\n\n\/* ======================================\n   1. PRIMO ANNO DEL BLOG\n====================================== *\/\n$first_post_date = $wpdb-&gt;get_var(&quot;\nSELECT post_date\nFROM $wpdb-&gt;posts\nWHERE post_status=&#039;publish&#039;\nAND post_type=&#039;post&#039;\nORDER BY post_date ASC\nLIMIT 1\n&quot;);\n\n$first_year = date(&#039;Y&#039;, strtotime($first_post_date));\n$current_year = date(&#039;Y&#039;);\n$year = isset($_GET&#x5B;&#039;yr&#039;]) ? intval($_GET&#x5B;&#039;yr&#039;]) : $current_year;\n\nif ($year &lt; $first_year) $year = $first_year;\nif ($year &gt; $current_year) $year = $current_year;\n\n\n\/* ======================================\n   2. DATE DEI POST (QUERY SQL OTTIMIZZATA + CACHE)\n====================================== *\/\n$cache_key = &#039;calendar_&#039;.$year;\n$post_dates = get_transient($cache_key);\nif ($post_dates === false){\n\t$post_dates = &#x5B;];\n\t$results = $wpdb-&gt;get_results($wpdb-&gt;prepare(&quot;\n\tSELECT DATE(post_date) as post_day, COUNT(ID) as total\n\tFROM $wpdb-&gt;posts\n\tWHERE post_status=&#039;publish&#039;\n\tAND post_type=&#039;post&#039;\n\tAND YEAR(post_date)=%d\n\tGROUP BY post_day\n\t&quot;, $year));\n\tforeach ($results as $row){\n\t\t$post_dates&#x5B;$row-&gt;post_day] = $row-&gt;total;\n\t}\n\tset_transient($cache_key,$post_dates,12*HOUR_IN_SECONDS);\n\t}\n\n\n\/* ======================================\n   3. NAVIGAZIONE CON TUTTI GLI ANNI\n====================================== *\/\necho &#039;&lt;div class=&quot;calendar-nav&quot;&gt;&#039;;\nfor ($y=$first_year; $y&lt;=$current_year; $y++){\n\tif ($y==$year){\n\t\techo &#039;&lt;span class=&quot;current-year&quot;&gt;&#039;.$y.&#039;&lt;\/span&gt;&#039;;\n\t}else{\n\t\techo &#039;&lt;a href=&quot;?yr=&#039;.$y.&#039;&quot;&gt;&#039;.$y.&#039;&lt;\/a&gt; &#039;;\n\t}\n}\necho &#039;&lt;\/div&gt;&#039;;\n\n\n\/* ======================================\n   4. CONTROLLO &quot;OGGI NEGLI ANNI PASSATI&quot;\n====================================== *\/\n$today_month = date(&#039;m&#039;);\n$today_day = date(&#039;d&#039;);\n$today_key = $year.&#039;-&#039;.$today_month.&#039;-&#039;.$today_day;\n$today_has_posts = isset($post_dates&#x5B;$today_key]);\n\n\n\/* ======================================\n   5. CONTENITORE ANNO\n====================================== *\/\necho &#039;&lt;div class=&quot;calendar-year&quot;&gt;&#039;;\n\n\n\/* ======================================\n   6. CICLO MESI\n====================================== *\/\nfor ($month=1; $month&lt;=12; $month++) {\n\techo &#039;&lt;div class=&quot;calendar-month-block&quot;&gt;&#039;;\n\t$month_name = date_i18n(&#039;F&#039;, mktime(0,0,0,$month,1,$year));\n\t$month_has_posts = false;\n\tforeach ($post_dates as $date =&gt; $count){\n\t\tif (strpos($date,$year.&#039;-&#039;.sprintf(&#039;%02d&#039;,$month))===0){\n\t\t\t$month_has_posts = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\/* titolo mese *\/\nif ($month_has_posts){\n\techo &#039;&lt;h3 class=&quot;month-title&quot;&gt;\n\t&lt;a href=&quot;&#039;.get_month_link($year,$month).&#039;&quot;&gt;&#039;.$month_name.&#039;&lt;\/a&gt;\n\t&lt;\/h3&gt;&#039;;\n\t}else{\n\techo &#039;&lt;h2 class=&quot;month-title&quot;&gt;&#039;.$month_name.&#039;&lt;\/h2&gt;&#039;;\n\t}\n\n\n\/* ======================================\n   7. TABELLA CALENDARIO\n====================================== *\/\necho &#039;&lt;table class=&quot;calendar-month&quot;&gt;&#039;;\necho &#039;&lt;thead&gt;&lt;tr&gt;&#039;;\n$weekdays = &#x5B;&#039;L&#039;,&#039;M&#039;,&#039;M&#039;,&#039;G&#039;,&#039;V&#039;,&#039;S&#039;,&#039;D&#039;]; \/\/da cambiare per le lingue diverse da quella italiana\nforeach ($weekdays as $w){\n\techo &#039;&lt;th&gt;&#039;.$w.&#039;&lt;\/th&gt;&#039;;\n\t}\necho &#039;&lt;\/tr&gt;&lt;\/thead&gt;&#039;;\necho &#039;&lt;tbody&gt;&lt;tr&gt;&#039;;\n\n\/* primo giorno mese *\/\n$first_day = date(&#039;N&#039;, strtotime(&quot;$year-$month-01&quot;));\nfor ($i=1;$i&lt;$first_day;$i++){\n\techo &#039;&lt;td class=&quot;empty&quot;&gt;&lt;\/td&gt;&#039;;\n\t}\n$days = cal_days_in_month(CAL_GREGORIAN,$month,$year);\n$weekday = $first_day;\n\n\n\/* ======================================\n   8. CICLO GIORNI\n====================================== *\/\nfor ($day=1;$day&lt;=$days;$day++){\n\t$date = $year.&#039;-&#039;.sprintf(&#039;%02d&#039;,$month).&#039;-&#039;.sprintf(&#039;%02d&#039;,$day);\n\t$is_today_past = false;\n\t\/* controllo &quot;oggi negli anni passati&quot; *\/\n\tif ($year &lt; $current_year &amp;&amp; $month==$today_month &amp;&amp; $day==$today_day){\n\t\t$is_today_past = true;\n\t}\n\t$classes = &#x5B;];\n\tif ($is_today_past) $classes&#x5B;] = &#039;today-past&#039;;\n\tif (isset($post_dates&#x5B;$date])){\n\t\t$classes&#x5B;] = &#039;has-posts&#039;;\n\t} else {\n\t\t$classes&#x5B;] = &#039;no-posts&#039;;\n\t}\n\techo &#039;&lt;td class=&quot;&#039;.implode(&#039; &#039;, $classes).&#039;&quot;&gt;&#039;;\n\tif (isset($post_dates&#x5B;$date])){\n\t\t$count = $post_dates&#x5B;$date];\n\t\t$title = ($count==1) ? &#039;1 articolo&#039; : $count.&#039; articoli&#039;;\n\t\techo &#039;&lt;a class=&quot;day-link&quot; href=&quot;&#039;.get_day_link($year,$month,$day).&#039;&quot; title=&quot;&#039;.$title.&#039;&quot;&gt;&#039;.$day.&#039;&lt;\/a&gt;&#039;;\n\t}else{\n\t\techo &#039;&lt;span class=&quot;day-number&quot;&gt;&#039;.$day.&#039;&lt;\/span&gt;&#039;;\n\t}\n\techo &#039;&lt;\/td&gt;&#039;;\n\tif ($weekday==7){\n\t\techo &#039;&lt;\/tr&gt;&lt;tr&gt;&#039;;\n\t\t$weekday=1;\n\t}else{\n\t\t$weekday++;\n\t}\n\t}\n\n\/* celle finali *\/\nwhile ($weekday&lt;=7){\n\techo &#039;&lt;td class=&quot;empty&quot;&gt;&lt;\/td&gt;&#039;;\n\t$weekday++;\n\t}\necho &#039;&lt;\/tr&gt;&lt;\/tbody&gt;&lt;\/table&gt;&#039;;\necho &#039;&lt;\/div&gt;&#039;;\n}\n\necho &#039;&lt;\/div&gt;&#039;;\n?&gt;\n<\/pre>\n<p>\nPer sicurezza preciso una cosa ovvia: con il&nbsp;codice PHP appena mostrato bisogna creare un&nbsp;template (una pagina *.php, per esempio calendarioblog.php), caricarlo nel tema del proprio sito WordPress e&nbsp;poi utilizzarlo per creare la&nbsp;pagina del calendario dalla admin.<br \/>\nIl&nbsp;codice CSS per la&nbsp;visualizzazione del calendario: si&nbsp;pu&ograve; copiarlo nel file style.css del tema oppure includerlo separatamente:<\/p>\n<pre class=\"brush: css; collapse: false; title: listing 2; notranslate\" title=\"listing 2\">\n\/* ===== navigazione anni ===== *\/\n.calendar-nav{\n\ttext-align:center;\n\tmargin:40px 0;\n\tfont-size:22px;\n\tline-height:2;\n}\n.calendar-nav a{\n\tmargin:0 10px;\n\ttext-decoration:none;\n}\n.current-year{\n\tfont-weight:bold;\n\tmargin:0 15px;\n}\n\/* ===== layout mesi ===== *\/\n.calendar-year{ display:block; }\n.calendar-month-block{ margin-bottom:40px; }\n\/* ===== titolo mese ===== *\/\n.month-title{\n\ttext-align:center;\n\tmargin-bottom:10px;\n}\n\/* ===== tabella ===== *\/\n.calendar-month{\n\twidth:100%;\n\tborder-collapse:collapse;\n}\n.calendar-month th{\n\tpadding:5px;\n\ttext-align:center;\n\tfont-weight:bold;\n}\n.calendar-month td{\n\tpadding:0;\n\theight:32px;\n\ttext-align:center;\n}\n\/* ===== giorni ===== *\/\n.day-number{\n\tdisplay:block;\n\tpadding:6px;\n}\n\/* celle con articoli *\/\n.calendar-month td.has-posts{ background:#C5C5C5; }\n\/* link riempie tutta la cella *\/\n.day-link{\n\tdisplay:block;\n\twidth:100%;\n\theight:100%;\n\tpadding:6px;\n\ttext-decoration:none;\n\tfont-weight:bold;\n\tbackground:transparent; \/* IMPORTANTISSIMO *\/\n}\n\/* celle senza articoli *\/\n.calendar-month td.no-posts{ background:#FFFFFF; }\n\/* numeri non linkati *\/\n.day-number{\n\tdisplay:block;\n\tpadding:6px;\n\tbackground:#FFFFFF; \/* garantisce bianco pieno *\/\n}\n.today-past{ outline:2px dashed #FF9800; }\n\/* hover *\/\n.day-link:hover{ background:#C5C5C5; }\n\/* celle vuote *\/\n.empty{ background:#FFFFFF; }\n\/* ===== layout desktop ===== *\/\n@media (min-width:1024px){\n.calendar-year{\n\tdisplay:grid;\n\tgrid-template-columns:repeat(3,1fr);\n\tgap:30px;\n\talign-items:start;\n}\n.calendar-month-block{ margin-bottom:0; }\n}\n<\/pre>\n<p>\nIn&nbsp;questa forma, con queste funzionalit&agrave;, &egrave;&nbsp;esattamente il&nbsp;calendario del blog di&nbsp;cui avevo bisogno. Cosa si&nbsp;potrebbe o&nbsp;si&nbsp;dovrebbe aggiungere? In&nbsp;realt&agrave;, non lo&nbsp;so&nbsp;nemmeno&nbsp;io. Se&nbsp;mi&nbsp;verr&agrave; in&nbsp;mente qualcosa (o&nbsp;se&nbsp;qualcuno mi&nbsp;dar&agrave; un&nbsp;suggerimento), pubblicher&ograve; una seconda versione e&nbsp;ne&nbsp;dar&ograve; notizia.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Il paragrafo dell\u2019\u201cInerario\u201d che illustra come creare un calendario annuale per un blog (o sito) basato su WordPress. Si tratta di un calendario con le date cliccabili e la possibilit\u00e0 di visualizzare anche gli anni passati del rispettivo blog\/sito.<br \/>\nQuesto paragrafo \u00e8 stato pensato per gli sviluppatori backend e frontend, ma i codici forniti possono essere utilizzati facilmente anche dalle persone meno esperte nella programmazione per il web.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":452,"menu_order":42,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-13715","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/eugigufo.net\/it\/wp-json\/wp\/v2\/pages\/13715","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eugigufo.net\/it\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/eugigufo.net\/it\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/eugigufo.net\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/eugigufo.net\/it\/wp-json\/wp\/v2\/comments?post=13715"}],"version-history":[{"count":1,"href":"https:\/\/eugigufo.net\/it\/wp-json\/wp\/v2\/pages\/13715\/revisions"}],"predecessor-version":[{"id":13770,"href":"https:\/\/eugigufo.net\/it\/wp-json\/wp\/v2\/pages\/13715\/revisions\/13770"}],"up":[{"embeddable":true,"href":"https:\/\/eugigufo.net\/it\/wp-json\/wp\/v2\/pages\/452"}],"wp:attachment":[{"href":"https:\/\/eugigufo.net\/it\/wp-json\/wp\/v2\/media?parent=13715"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}