from . import models
+admin.site.register(models.Campaign)
+
+
class BannerAdmin(TranslationAdmin):
list_display = [
'place', 'text',
--- /dev/null
+# Generated by Django 4.0.8 on 2025-11-25 15:13
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('catalogue', '0051_book_has_audio'),
+ ('annoy', '0018_alter_banner_style'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Campaign',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(help_text='Dla zespołu', max_length=255)),
+ ('image', models.FileField(blank=True, upload_to='annoy/banners/', verbose_name='obraz')),
+ ],
+ ),
+ migrations.AddField(
+ model_name='banner',
+ name='books',
+ field=models.ManyToManyField(blank=True, to='catalogue.book'),
+ ),
+ migrations.AlterField(
+ model_name='banner',
+ name='place',
+ field=models.SlugField(choices=[('top', 'U góry wszystkich stron'), ('book-page', 'Strona książki'), ('book-page-center', 'Strona książki, środek'), ('book-text-intermission', 'Przerwa w treści książki'), ('book-fragment-list', 'Obok listy fragmentów książki'), ('blackout', 'Blackout'), ('crisis', 'Kryzysowa')], verbose_name='miejsce'),
+ ),
+ migrations.AddField(
+ model_name='banner',
+ name='campaign',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='annoy.campaign'),
+ ),
+ ]
from .places import PLACES, PLACE_CHOICES, STYLES
+class Campaign(models.Model):
+ name = models.CharField(max_length=255, help_text='Dla zespołu')
+ image = models.FileField('obraz', upload_to='annoy/banners/', blank=True)
+
+ def __str__(self):
+ return self.name
+
+
class Banner(models.Model):
place = models.SlugField('miejsce', choices=PLACE_CHOICES)
+ campaign = models.ForeignKey(Campaign, models.PROTECT, null=True, blank=True)
+
style = models.CharField(
'styl', max_length=255, blank=True,
choices=STYLES,
help_text='Bannery z wyższym priorytetem mają pierwszeństwo.')
since = models.DateTimeField('od', null=True, blank=True)
until = models.DateTimeField('do', null=True, blank=True)
+ books = models.ManyToManyField('catalogue.Book', blank=True)
+
target = models.IntegerField('cel', null=True, blank=True)
progress = models.IntegerField('postęp', null=True, blank=True)
show_members = models.BooleanField('widoczny dla członków klubu', default=False)
def get_text(self):
return Template(self.text).render(Context())
+ def get_image(self):
+ if self.campaign and self.campaign.image:
+ return self.campaign.image
+ else:
+ return self.image
+
@classmethod
- def choice(cls, place, request, exemptions=True):
+ def choice(cls, place, request, exemptions=True, book=None):
Membership = apps.get_model('club', 'Membership')
if exemptions and hasattr(request, 'annoy_banner_exempt'):
until__lt=n
).order_by('-priority', '?')
+ if book is None:
+ banners = banners.filter(books=None)
+ else:
+ banners = banners.filter(models.Q(books=None) | models.Q(books=book))
+
+
if not request.user.is_authenticated:
banners = banners.filter(only_authenticated=False)
PLACE_DEFINITIONS = [
('top', 'U góry wszystkich stron', True),
('book-page', 'Strona książki', False),
+ ('book-page-center', 'Strona książki, środek', False),
('book-text-intermission', 'Przerwa w treści książki', False),
('book-fragment-list', 'Obok listy fragmentów książki', False),
('blackout', 'Blackout', True, (
annoy-banner
annoy-banner_{{ banner.place }}
annoy-banner-style_{{ banner.style }}
- {% if banner.image %}with-image{% endif %}
+ {% if banner.get_image %}with-image{% endif %}
{% if banner.smallfont %}banner-smallfont{% endif %}
"
id="annoy-banner-{{ banner.id }}"
{% endif %}
<div class="annoy-banner-inner">
- {% if banner.image %}
- <img src="{{ banner.image.url }}">
+ {% if banner.get_image %}
+ <div>
+ <img src="{{ banner.get_image.url }}">
+ </div>
{% endif %}
<div class="text">
{{ banner.get_text|safe|linebreaks }}
@register.inclusion_tag('annoy/banner.html', takes_context=True)
-def annoy_banner(context, place):
- banners = Banner.choice(place, request=context['request'])
+def annoy_banner(context, place, **kwargs):
+ banners = Banner.choice(place, request=context['request'], **kwargs)
return {
'banner': banners.first(),
'closable': PLACES.get(place, False),
<button class="l-article__read-more" aria-label="{% trans 'Kliknij aby rozwinąć' %}" data-label="{% trans 'Czytaj więcej' %}" data-action="{% trans 'Zwiń tekst' %}">{% trans 'Czytaj więcej' %}</button>
</article>
{% if accessible %}
- <div class="c-support">
- <div>
- <h2>
- {% blocktrans trimmed %}
- Ta książka jest dostępna dla tysięcy dzieciaków dzięki
- <span>darowiznom</span> od osób takich jak <span>Ty</span>!
- {% endblocktrans %}
- </h2>
- <a href="{% url 'club_join' %}?pk_campaign=layout">{% trans "Dorzuć się!" %}</a>
- </div>
- <div class="bg">
- <!-- img src="{% static '2022/images/dziecko.jpeg' %}" alt="Dorzuć się!" -->
- </div>
- </div>
+ {% annoy_banner 'book-page-center' book=book %}
{% endif %}
</div>
{% endwith %}
}
}
}
+
+.annoy-banner_book-page-center {
+ background: white;
+ margin-top: 20px;
+ padding: 20px;
+ border: 1px solid #018189;
+ border-radius: 15px;
+ color:#018189;
+
+ .annoy-banner-inner {
+ display: flex;
+ gap: 15px;
+ img {
+ max-width: 200px;
+ }
+ p {
+ margin: 0;
+ }
+ }
+}