diff --git a/README.md b/README.md index ec937158fe6c6d0a87e523e94c756b5102b72081..f12ebec23dd852f41254d6301cc04c517224e376 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,20 @@ jako přehled pluginů a rozšíření pro Wagtail. Appky v sobě mají modely pro stránky a statické soubory a templaty. Momentálně se mezi weby nic z toho nesdílí. +### Kalendáře + +Pro práci s kalendáři v iCal formátu je připravena appka `calendar_utils`. + +Poskytuje `CalendarMixin` do modelu, který přidá fieldy `calendar_url` pro +editaci a `calendar` pro vazbu na model `Calendar` (který se plní a automaticky +spravuje na pozadí). Typicky se použije ve Wagtail settings pro web, kde stačí +`calendar_url` zpřístupnit pro editaci. + +Kalendář se stáhne při uložení modelu obsahujícího `CalendarMixin`. + +Appka přidává management command `update_callendars`, který stahuje a updatuje +kalendáře. Je třeba ho pravidelně volat na pozadí (přes CRON). + ## Deployment ### Konfigurace diff --git a/senat_campaign/migrations/0003_auto_20200523_0241.py b/senat_campaign/migrations/0003_auto_20200523_0241.py new file mode 100644 index 0000000000000000000000000000000000000000..f56e67570500c4accc46fafbfec7bbe99c3fda2d --- /dev/null +++ b/senat_campaign/migrations/0003_auto_20200523_0241.py @@ -0,0 +1,31 @@ +# Generated by Django 3.0.6 on 2020-05-23 00:41 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("calendar_utils", "0001_initial"), + ("senat_campaign", "0002_senatcampaignwebsettings_matomo_id"), + ] + + operations = [ + migrations.AddField( + model_name="senatcampaignwebsettings", + name="calendar", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="calendar_utils.Calendar", + ), + ), + migrations.AddField( + model_name="senatcampaignwebsettings", + name="calendar_url", + field=models.URLField( + blank=True, null=True, verbose_name="URL kalendáře ve formátu iCal" + ), + ), + ] diff --git a/senat_campaign/models.py b/senat_campaign/models.py index f36fee3c80389645c42460f9ececb6872fc96f64..e2a066c07158012316ff80ed3f20adf5fa04ea90 100644 --- a/senat_campaign/models.py +++ b/senat_campaign/models.py @@ -13,6 +13,8 @@ from wagtail.documents.blocks import DocumentChooserBlock from wagtail.images.blocks import ImageChooserBlock from wagtail.images.edit_handlers import ImageChooserPanel +from calendar_utils.models import CalendarMixin + class SenatCampaignHomePage(Page): # top section @@ -81,7 +83,7 @@ class SenatCampaignHomePage(Page): is_home = True class Meta: - verbose_name = f"Senát kampaň" + verbose_name = "Senát kampaň" def get_context(self, request): context = super().get_context(request) @@ -128,7 +130,7 @@ class SenatCampaignNewsIndexPage(Page): is_home = False class Meta: - verbose_name = f"Aktuality" + verbose_name = "Aktuality" def get_context(self, request): context = super().get_context(request) @@ -163,7 +165,7 @@ class SenatCampaignNewsPage(Page): is_home = False class Meta: - verbose_name = f"Aktualita" + verbose_name = "Aktualita" def get_context(self, request): context = super().get_context(request) @@ -208,7 +210,7 @@ class SenatCampaignProgramPage(Page): is_home = False class Meta: - verbose_name = f"Program" + verbose_name = "Program" class SenatCampaignCookiesPage(Page): @@ -225,7 +227,7 @@ class SenatCampaignCookiesPage(Page): is_home = False class Meta: - verbose_name = f"Cookies" + verbose_name = "Cookies" class ContactBlock(blocks.StructBlock): @@ -241,7 +243,7 @@ class ContactBlock(blocks.StructBlock): @register_setting -class SenatCampaignWebSettings(BaseSetting): +class SenatCampaignWebSettings(BaseSetting, CalendarMixin): first_name = models.CharField("jméno kandidáta", max_length=250) last_name = models.CharField("příjmení kandidáta", max_length=250) facebook = models.URLField("Facebook URL", blank=True, null=True) @@ -255,13 +257,13 @@ class SenatCampaignWebSettings(BaseSetting): "Matomo ID pro sledování návštěvnosti", blank=True, null=True ) - # TODO Matomo # TODO donations first_tab_panels = [ FieldPanel("first_name"), FieldPanel("last_name"), FieldPanel("matomo_id"), + FieldPanel("calendar_url"), ] second_tab_panels = [ @@ -283,8 +285,10 @@ class SenatCampaignWebSettings(BaseSetting): ] ) + select_related = ["calendar"] + class Meta: - verbose_name = f"Senát kampaň" + verbose_name = "Senát kampaň" @property def full_name(self): @@ -299,9 +303,8 @@ class SenatCampaignWebSettings(BaseSetting): return SenatCampaignNewsIndexPage.objects.in_site(self.site).live().exists() @property - def has_callendar(self): - # TODO - return False + def has_calendar(self): + return self.calendar_id is not None @property def has_donations(self): diff --git a/senat_campaign/templates/senat_campaign/base.html b/senat_campaign/templates/senat_campaign/base.html index 0fa291ebc09fc0688eb071d086cd8b3a648f4801..8ea1c7cd0497930302cb0c7d12aabed671aa1167 100644 --- a/senat_campaign/templates/senat_campaign/base.html +++ b/senat_campaign/templates/senat_campaign/base.html @@ -146,7 +146,7 @@ {% endif %} </li> {% endif %} - {% if web_settings.has_callendar %} + {% if web_settings.has_calendar %} <li class="nav-item"> {% if page.is_home %} <a class="nav-link js-scroll-anchor" href="#kalendar">Kalendář</a> diff --git a/senat_campaign/templates/senat_campaign/calendar_event_snippet.html b/senat_campaign/templates/senat_campaign/calendar_event_snippet.html new file mode 100644 index 0000000000000000000000000000000000000000..b8cee4a8074b33486b4da805cb54781e7118a79d --- /dev/null +++ b/senat_campaign/templates/senat_campaign/calendar_event_snippet.html @@ -0,0 +1,13 @@ +<div class="calendar__row"> + <div class="calendar__row__date1"> + <h3>{{ event.begin|date:"d" }}.</h3> + </div> + <div class="calendar__row__date2"> + <h6>{{ event.begin|date:"j.n.Y" }}</h6> + <p>{{ event.duration }}</p> + </div> + <div class="calendar__row__content"> + <h6>{{ event.name }}</h6> + <p>{{ event.location }}</p> + </div> +</div><!-- /calendar__row --> diff --git a/senat_campaign/templates/senat_campaign/senat_campaign_home_page.html b/senat_campaign/templates/senat_campaign/senat_campaign_home_page.html index a3bddbc395928f384ff27b36352f15fb4ae0ef4a..f233b2bdbbdf43258b57d2cc820c25fbe704195e 100644 --- a/senat_campaign/templates/senat_campaign/senat_campaign_home_page.html +++ b/senat_campaign/templates/senat_campaign/senat_campaign_home_page.html @@ -151,7 +151,7 @@ {% if web_settings.has_news %} - <section class="section--primary{% if web_settings.has_callendar %} section--no-bottom-padding{% endif %}" id="aktuality"> + <section class="section--primary{% if web_settings.has_calendar %} section--no-bottom-padding{% endif %}" id="aktuality"> <div class="container"> <h2 class="lead page-subheading mb-4">Aktuality</h2> @@ -184,7 +184,7 @@ {% endif %} - {% if web_settings.has_callendar %} + {% if web_settings.has_calendar %} <section class="section--primary" id="kalendar"> <div class="container"> @@ -201,95 +201,13 @@ </div><!-- /calendar__left --> <div class="calendar__right"> - - <div class="calendar__row"> - <div class="calendar__row__date1"> - <h3>18.</h3> - </div> - <div class="calendar__row__date2"> - <h6>18.4.2020</h6> - <p>celý den</p> - </div> - <div class="calendar__row__content"> - <h6>Rozdávání novin na vlakovém nádraží Beroun</h6> - <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sollicitudin. Aliquam erat volutpat. - </p> - </div> - </div><!-- /calendar__row --> - - <div class="calendar__row"> - <div class="calendar__row__date1"> - <h3>17.</h3> - </div> - <div class="calendar__row__date2"> - <h6>17.4.2020</h6> - <p>13:00 - 17:00</p> - </div> + {% for event in web_settings.calendar.actual_events %} + {% include "senat_campaign/calendar_event_snippet.html" %} + {% empty %} <div class="calendar__row__content"> - <h6>Stánkování Náměstí Republiky</h6> - <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sollicitudin. </p> + <p>Žádné události.</p> </div> - </div><!-- /calendar__row --> - - <div class="calendar__row"> - <div class="calendar__row__date1"> - <h3>16.</h3> - </div> - <div class="calendar__row__date2"> - <h6>16.4.2020</h6> - <p>20:00 - 22:00</p> - </div> - <div class="calendar__row__content"> - <h6>Posezení se senátorem</h6> - <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sollicitudin. Aliquam erat volutpat. - Maecenas sollicitudin. Aliquam erat volutpat.</p> - </div> - </div><!-- /calendar__row --> - - <div class="calendar__row"> - <div class="calendar__row__date1"> - <h3>15.</h3> - </div> - <div class="calendar__row__date2"> - <h6>15.4.2020</h6> - <p>celý den</p> - </div> - <div class="calendar__row__content"> - <h6>Pivobraní Mikulovice náměstí</h6> - <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sollicitudin. Aliquam erat volutpat. - </p> - </div> - </div><!-- /calendar__row --> - - <div class="calendar__row"> - <div class="calendar__row__date1"> - <h3>14.</h3> - </div> - <div class="calendar__row__date2"> - <h6>14.4.2020</h6> - <p>celý den</p> - </div> - <div class="calendar__row__content"> - <h6>Vinobraní na náměstí Chrudim</h6> - <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sollicitudin. Aliquam erat volutpat. - </p> - </div> - </div><!-- /calendar__row --> - - <div class="calendar__row"> - <div class="calendar__row__date1"> - <h3>13.</h3> - </div> - <div class="calendar__row__date2"> - <h6>13.4.2020</h6> - <p>celý den</p> - </div> - <div class="calendar__row__content"> - <h6>Stánkování na farmářských trzích Bohnice</h6> - <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sollicitudin. Aliquam erat volutpat. - </p> - </div> - </div><!-- /calendar__row --> + {% endfor %} </div><!-- /calendar__right --> @@ -329,7 +247,7 @@ {% endif %} - {% if web_settings.has_callendar %} + {% if web_settings.has_calendar %} <!-- Calendar modal --> <div class="modal fade calendar__modal" id="calendarModal" tabindex="-1" role="dialog" aria-labelledby="calendarModalTitle" aria-hidden="true"> @@ -359,122 +277,28 @@ aria-labelledby="upcomingEvents-tab"> <div class="calendar__right"> - <div class="calendar__row"> - <div class="calendar__row__date1"> - <h3>18.</h3> - </div> - <div class="calendar__row__date2"> - <h6>18.4.2020</h6> - <p>celý den</p> - </div> - <div class="calendar__row__content"> - <h6>Rozdávání novin na vlakovém nádraží Beroun</h6> - <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sollicitudin. Aliquam erat - volutpat. - </p> - </div> - </div><!-- /calendar__row --> - - <div class="calendar__row"> - <div class="calendar__row__date1"> - <h3>17.</h3> - </div> - <div class="calendar__row__date2"> - <h6>17.4.2020</h6> - <p>13:00 - 17:00</p> - </div> - <div class="calendar__row__content"> - <h6>Stánkování Náměstí Republiky</h6> - <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sollicitudin. </p> - </div> - </div><!-- /calendar__row --> - - <div class="calendar__row"> - <div class="calendar__row__date1"> - <h3>16.</h3> - </div> - <div class="calendar__row__date2"> - <h6>16.4.2020</h6> - <p>20:00 - 22:00</p> - </div> - <div class="calendar__row__content"> - <h6>Posezení se senátorem</h6> - <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sollicitudin. Aliquam erat - volutpat. - Maecenas sollicitudin. Aliquam erat volutpat.</p> - </div> - </div><!-- /calendar__row --> - - <div class="calendar__row"> - <div class="calendar__row__date1"> - <h3>15.</h3> - </div> - <div class="calendar__row__date2"> - <h6>15.4.2020</h6> - <p>celý den</p> - </div> - <div class="calendar__row__content"> - <h6>Pivobraní Mikulovice náměstí</h6> - <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sollicitudin. Aliquam erat - volutpat. - </p> - </div> - </div><!-- /calendar__row --> - <div class="calendar__row"> - <div class="calendar__row__date1"> - <h3>14.</h3> - </div> - <div class="calendar__row__date2"> - <h6>14.4.2020</h6> - <p>celý den</p> - </div> + {% for event in web_settings.calendar.future_events %} + {% include "senat_campaign/calendar_event_snippet.html" %} + {% empty %} <div class="calendar__row__content"> - <h6>Vinobraní na náměstí Chrudim</h6> - <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sollicitudin. Aliquam erat - volutpat. - </p> + <p>Žádné události.</p> </div> - </div><!-- /calendar__row --> + {% endfor %} - <div class="calendar__row"> - <div class="calendar__row__date1"> - <h3>13.</h3> - </div> - <div class="calendar__row__date2"> - <h6>13.4.2020</h6> - <p>celý den</p> - </div> - <div class="calendar__row__content"> - <h6>Stánkování na farmářských trzích Bohnice</h6> - <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sollicitudin. Aliquam erat - volutpat. - </p> - </div> - </div><!-- /calendar__row --> </div><!-- /calendar__right --> - </div><!-- /tab-pane --> <div class="tab-pane fade" id="pastEvents" role="tabpanel" aria-labelledby="pastEvents-tab"> - <div class="calendar__right"> - <div class="calendar__row"> - <div class="calendar__row__date1"> - <h3>18.</h3> - </div> - <div class="calendar__row__date2"> - <h6>18.4.2020</h6> - <p>celý den</p> - </div> + {% for event in web_settings.calendar.past_events|slice:":10" %} + {% include "senat_campaign/calendar_event_snippet.html" %} + {% empty %} <div class="calendar__row__content"> - <h6>Rozdávání novin na vlakovém nádraží Beroun</h6> - <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sollicitudin. Aliquam erat - volutpat. - </p> + <p>Žádné události.</p> </div> - </div><!-- /calendar__row --> + {% endfor %} </div><!-- /calendar__right --> </div><!-- /tab-pane -->