From: Marcin Koziej Date: Thu, 26 Jan 2012 13:17:43 +0000 (+0100) Subject: merge X-Git-Url: https://git.mdrn.pl/wolnelektury.git/commitdiff_plain/71209be8f9c399340bddb819f71e99ecf116187b?hp=4cf27ad4ae5ac3610e857379b2a788582580aa5b merge --- diff --git a/README.md b/README.md index 725dc7c2d..fd193b233 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ django-compress - License: [MIT License](http://www.opensource.org/licenses/mit-license.php) - Type: library (Django application) - django-chunks +django-chunks ------------- - Source: [Google Code](http://code.google.com/p/django-chunks/) - Authors: Clint Ecker @@ -131,19 +131,7 @@ django-newtagging - Type: library (Django aplication) - Notes: Aplication based on [django-tagging](http://code.google.com/p/django-tagging/), also [MIT](http://www.opensource.org/licenses/mit-license.php) license. -django-piston (0.2.3rc) ------------------------- - - http://bitbucket.org/jespern/django-piston/wiki/Home -markupstring ------------- - - Source: [ASPN Cookbook](http://code.activestate.com/recipes/389023/) - - Authors: Thomas Hinkle - - License: [MIT License](http://code.activestate.com/help/terms/) - - Type: library - - Notes: Patched by Marek Stępniowski to accept Unicode strings - - Authors ======= diff --git a/apps/catalogue/fixtures/collection-boy.json b/apps/catalogue/fixtures/collection-boy.json index 9a0e7781a..1328b132b 100644 --- a/apps/catalogue/fixtures/collection-boy.json +++ b/apps/catalogue/fixtures/collection-boy.json @@ -3,7 +3,7 @@ "pk": "promo", "model": "chunks.chunk", "fields": { - "content": "

Biblioteczka Boya

\r\n\r\n

T\u0142umaczenia literatury francuskiej i nie tylko.

\r\n\r\n

Biblioteczka Boya \u21d2

", + "content": "

\r\n\r\n\r\nOh Boy!\r\n\r\n\r\n

\r\n\r\n\r\nBiblioteczka Boya\r\n\r\n\r\n

\r\n\r\n\r\n

T\u0142umaczenia literatury francuskiej i nie tylko.

\r\n\r\n

Biblioteczka Boya \u21d2

\r\n\r\n\r\n
", "description": "boks promocyjny na g\u0142\u00f3wnej" } }, diff --git a/apps/catalogue/models.py b/apps/catalogue/models.py index a94411191..7f20b4e59 100644 --- a/apps/catalogue/models.py +++ b/apps/catalogue/models.py @@ -24,7 +24,7 @@ from django.conf import settings from newtagging.models import TagBase, tags_updated from newtagging import managers from catalogue.fields import JSONField, OverwritingFileField -from catalogue.utils import create_zip, split_tags +from catalogue.utils import create_zip, split_tags, truncate_html_words from catalogue.tasks import touch_tag, index_book from shutil import copy from glob import glob @@ -565,7 +565,6 @@ class Book(models.Model): def build_html(self): - from markupstring import MarkupString from django.core.files.base import ContentFile from slughifi import slughifi from librarian import html @@ -609,10 +608,9 @@ class Book(models.Model): continue text = fragment.to_string() - short_text = '' - markup = MarkupString(text) - if (len(markup) > 240): - short_text = unicode(markup[:160]) + short_text = truncate_html_words(text, 15) + if text == short_text: + short_text = '' new_fragment = Fragment.objects.create(anchor=fragment.id, book=self, text=text, short_text=short_text) @@ -1003,6 +1001,10 @@ class Fragment(models.Model): for lang, langname in settings.LANGUAGES: permanent_cache.delete(cache_key % (self.id, lang)) + def get_short_text(self): + """Returns short version of the fragment.""" + return self.short_text if self.short_text else self.text + def short_html(self): if self.id: cache_key = "Fragment.short_html/%d/%s" % (self.id, get_language()) diff --git a/apps/catalogue/templatetags/catalogue_tags.py b/apps/catalogue/templatetags/catalogue_tags.py index c2d7dd6d5..961cc015f 100644 --- a/apps/catalogue/templatetags/catalogue_tags.py +++ b/apps/catalogue/templatetags/catalogue_tags.py @@ -363,18 +363,3 @@ def tag_url(category, slug): return reverse('catalogue.views.tagged_object_list', args=[ '/'.join((Tag.categories_dict[category], slug)) ]) - - -@register.filter -@stringfilter -def removewholetags(value, tags): - """Removes a space separated list of [X]HTML tags from the output. - - FIXME: It makes the assumption the removed tags aren't nested. - - """ - tags = [re.escape(tag) for tag in tags.split()] - tags_re = u'(%s)' % u'|'.join(tags) - tag_re = re.compile(ur'<%s[^>]*>.*?' % tags_re, re.U) - value = tag_re.sub(u'', value) - return value diff --git a/apps/catalogue/utils.py b/apps/catalogue/utils.py index 0fdeaf810..185f5fa34 100644 --- a/apps/catalogue/utils.py +++ b/apps/catalogue/utils.py @@ -5,6 +5,7 @@ from __future__ import with_statement import random +import re import time from base64 import urlsafe_b64encode @@ -12,6 +13,7 @@ from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpRespons from django.core.files.uploadedfile import UploadedFile from django.core.files.base import File from django.core.files.storage import DefaultStorage +from django.utils.encoding import force_unicode from django.utils.hashcompat import sha_constructor from django.conf import settings from celery.task import task @@ -51,7 +53,7 @@ class ExistingFile(UploadedFile): def __init__(self, path, *args, **kwargs): self.path = path - return super(ExistingFile, self).__init__(*args, **kwargs) + super(ExistingFile, self).__init__(*args, **kwargs) def temporary_file_path(self): return self.path @@ -189,3 +191,72 @@ class MultiQuerySet(object): offset = 0 stop = total_len - len(items) continue + + +def truncate_html_words(s, num, end_text='...'): + """Truncates HTML to a certain number of words (not counting tags and + comments). Closes opened tags if they were correctly closed in the given + html. Takes an optional argument of what should be used to notify that the + string has been truncated, defaulting to ellipsis (...). + + Newlines in the HTML are preserved. + + This is just a version of django.utils.text.truncate_html_words with no space before the end_text. + """ + s = force_unicode(s) + length = int(num) + if length <= 0: + return u'' + html4_singlets = ('br', 'col', 'link', 'base', 'img', 'param', 'area', 'hr', 'input') + # Set up regular expressions + re_words = re.compile(r'&.*?;|<.*?>|(\w[\w-]*)', re.U) + re_tag = re.compile(r'<(/)?([^ ]+?)(?: (/)| .*?)?>') + # Count non-HTML words and keep note of open tags + pos = 0 + end_text_pos = 0 + words = 0 + open_tags = [] + while words <= length: + m = re_words.search(s, pos) + if not m: + # Checked through whole string + break + pos = m.end(0) + if m.group(1): + # It's an actual non-HTML word + words += 1 + if words == length: + end_text_pos = pos + continue + # Check for tag + tag = re_tag.match(m.group(0)) + if not tag or end_text_pos: + # Don't worry about non tags or tags after our truncate point + continue + closing_tag, tagname, self_closing = tag.groups() + tagname = tagname.lower() # Element names are always case-insensitive + if self_closing or tagname in html4_singlets: + pass + elif closing_tag: + # Check for match in open tags list + try: + i = open_tags.index(tagname) + except ValueError: + pass + else: + # SGML: An end tag closes, back to the matching start tag, all unclosed intervening start tags with omitted end tags + open_tags = open_tags[i+1:] + else: + # Add it to the start of the open tags list + open_tags.insert(0, tagname) + if words <= length: + # Don't try to close tags if we don't need to truncate + return s + out = s[:end_text_pos] + if end_text: + out += end_text + # Close any tags still open + for tag in open_tags: + out += '' % tag + # Return string + return out diff --git a/apps/catalogue/views.py b/apps/catalogue/views.py index 14147c886..9044a809e 100644 --- a/apps/catalogue/views.py +++ b/apps/catalogue/views.py @@ -4,32 +4,25 @@ # import re import itertools -from datetime import datetime from django.conf import settings from django.template import RequestContext from django.shortcuts import render_to_response, get_object_or_404 from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponsePermanentRedirect from django.core.urlresolvers import reverse -from django.db.models import Count, Sum, Q +from django.db.models import Q from django.contrib.auth.decorators import login_required, user_passes_test from django.utils.datastructures import SortedDict -from django.views.decorators.http import require_POST -from django.contrib import auth -from django.contrib.auth.forms import UserCreationForm, AuthenticationForm from django.utils.http import urlquote_plus -from django.views.decorators import cache from django.utils import translation from django.utils.translation import ugettext as _ -from django.views.generic.list_detail import object_list -from ajaxable.utils import LazyEncoder, JSONResponse, AjaxableFormView +from ajaxable.utils import JSONResponse, AjaxableFormView from catalogue import models from catalogue import forms from catalogue.utils import (split_tags, AttachmentHttpResponse, async_build_pdf, MultiQuerySet) -from catalogue.tasks import touch_tag from pdcounter import models as pdcounter_models from pdcounter import views as pdcounter_views from suggest.forms import PublishingSuggestForm diff --git a/apps/search/templatetags/search_tags.py b/apps/search/templatetags/search_tags.py index 5bbc42225..0e20913d5 100644 --- a/apps/search/templatetags/search_tags.py +++ b/apps/search/templatetags/search_tags.py @@ -47,4 +47,5 @@ def book_searched(context, result): 'main_link': book.get_absolute_url(), 'request': context.get('request'), 'hits': hits, + 'main_link': book.get_absolute_url(), } diff --git a/apps/social/admin.py b/apps/social/admin.py index 298638ae5..f32f42612 100755 --- a/apps/social/admin.py +++ b/apps/social/admin.py @@ -7,4 +7,8 @@ from django.contrib import admin from social.models import Cite -admin.site.register(Cite) +class CiteAdmin(admin.ModelAdmin): + list_display = ['text', 'vip', 'small'] + + +admin.site.register(Cite, CiteAdmin) diff --git a/apps/social/migrations/0002_auto__add_field_cite_small.py b/apps/social/migrations/0002_auto__add_field_cite_small.py new file mode 100644 index 000000000..4490f74b5 --- /dev/null +++ b/apps/social/migrations/0002_auto__add_field_cite_small.py @@ -0,0 +1,58 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Adding field 'Cite.small' + db.add_column('social_cite', 'small', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False) + + + def backwards(self, orm): + + # Deleting field 'Cite.small' + db.delete_column('social_cite', 'small') + + + models = { + 'catalogue.book': { + 'Meta': {'ordering': "('sort_key',)", 'object_name': 'Book'}, + '_related_info': ('jsonfield.fields.JSONField', [], {'null': 'True', 'blank': 'True'}), + 'changed_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}), + 'common_slug': ('django.db.models.fields.SlugField', [], {'max_length': '120', 'db_index': 'True'}), + 'cover': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'epub_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), + 'extra_info': ('catalogue.fields.JSONField', [], {'default': "'{}'"}), + 'gazeta_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + 'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.CharField', [], {'default': "'pol'", 'max_length': '3', 'db_index': 'True'}), + 'mobi_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['catalogue.Book']"}), + 'parent_number': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'pdf_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '120', 'db_index': 'True'}), + 'sort_key': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '120'}), + 'txt_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), + 'wiki_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + 'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}) + }, + 'social.cite': { + 'Meta': {'object_name': 'Cite'}, + 'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Book']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'link': ('django.db.models.fields.URLField', [], {'max_length': '200'}), + 'small': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'text': ('django.db.models.fields.TextField', [], {}), + 'vip': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['social'] diff --git a/apps/social/models.py b/apps/social/models.py index 225477e20..753980577 100644 --- a/apps/social/models.py +++ b/apps/social/models.py @@ -4,6 +4,7 @@ # from django.db import models from django.utils.translation import ugettext_lazy as _ +from django.core.urlresolvers import reverse from catalogue.models import Book @@ -11,8 +12,16 @@ from catalogue.models import Book class Cite(models.Model): book = models.ForeignKey(Book) text = models.TextField(_('text')) + small = models.BooleanField(_('small'), default=False, help_text=_('Make this cite display smaller.')) vip = models.CharField(_('VIP'), max_length=128, null=True, blank=True) link = models.URLField(_('link')) + class Meta: + ordering = ('vip', 'text') + + def __unicode__(self): + return u"%s: %s…" % (self.vip, self.text[:60]) + def get_absolute_url(self): - return self.link + """This is used for testing.""" + return "%s?choose_cite=%d" % (reverse('main_page'), self.id) diff --git a/apps/social/templates/social/cite_promo.html b/apps/social/templates/social/cite_promo.html index 04866f14b..0554d23af 100755 --- a/apps/social/templates/social/cite_promo.html +++ b/apps/social/templates/social/cite_promo.html @@ -1,14 +1,14 @@ {% load i18n %} {% if cite %} - + {% if cite.vip %} -

{{ cite.vip }} {% trans "recommends" %}:

+

{{ cite.vip }} {% trans "recommends" %}:

{% endif %}
- {{ cite.text|linebreaks|safe }} + {{ cite.text|linebreaksbr|safe }}
-

{{ cite.book.pretty_title }}

+

{{ cite.book.pretty_title }}

{% else %} {% if fallback %} diff --git a/apps/social/templatetags/social_tags.py b/apps/social/templatetags/social_tags.py index e78f20f0a..29a43098b 100755 --- a/apps/social/templatetags/social_tags.py +++ b/apps/social/templatetags/social_tags.py @@ -12,20 +12,27 @@ register = template.Library() register.filter('likes', likes) -@register.inclusion_tag('social/cite_promo.html') -def cite_promo(ctx=None, fallback=False): +@register.inclusion_tag('social/cite_promo.html', takes_context=True) +def cite_promo(context, ctx=None, fallback=False): """Choose""" - if ctx is None: - cites = Cite.objects.all() - elif isinstance(ctx, Book): - cites = ctx.cite_set.all() - if not cites.exists(): - cites = cites_for_tags([ctx.book_tag()]) - else: - cites = cites_for_tags(ctx) + try: + request = context['request'] + assert request.user.is_staff + assert 'choose_cite' in request.GET + cite = Cite.objects.get(pk=request.GET['choose_cite']) + except AssertionError, Cite.DoesNotExist: + if ctx is None: + cites = Cite.objects.all() + elif isinstance(ctx, Book): + cites = ctx.cite_set.all() + if not cites.exists(): + cites = cites_for_tags([ctx.book_tag()]) + else: + cites = cites_for_tags(ctx) + cite = cites.order_by('?')[0] if cites.exists() else None return { - 'cite': cites.order_by('?')[0] if cites.exists() else None, + 'cite': cite, 'fallback': fallback, 'ctx': ctx, } diff --git a/lib/librarian b/lib/librarian index e394602de..b24b166cc 160000 --- a/lib/librarian +++ b/lib/librarian @@ -1 +1 @@ -Subproject commit e394602de9243608d1e99a3de448a75646f1a77f +Subproject commit b24b166cc4de6ba7e9b1559717bb5ff6e27bdacd diff --git a/lib/markupstring.py b/lib/markupstring.py deleted file mode 100644 index 0e273f2a1..000000000 --- a/lib/markupstring.py +++ /dev/null @@ -1,97 +0,0 @@ -# Code taken from ActiveState Python recipes: -# http://code.activestate.com/recipes/389023/ -# -# Changed by Marek Stepniowski to handle unicode characters -import xml.sax - - -class simpleHandler(xml.sax.ContentHandler): - """A simple handler that provides us with indices of marked up content.""" - def __init__(self): - self.elements = [] #this will contain a list of elements and their start/end indices - self.open_elements = [] #this holds info on open elements while we wait for their close - self.content = "" - - def startElement(self, name, attrs): - if name == 'foobar': return # we require an outer wrapper, which we promptly ignore. - self.open_elements.append({'name':name, - 'attrs':attrs.copy(), - 'start':len(self.content), - }) - - def endElement(self, name): - if name == 'foobar': return # we require an outer wrapper, which we promptly ignore. - for i in range(len(self.open_elements)): - e = self.open_elements[i] - if e['name'] == name: - # append a (start,end), name, attrs - self.elements.append(((e['start'], #start position - len(self.content)), # current (end) position - e['name'], e['attrs']) - ) - del self.open_elements[i] - return - - def characters(self, chunk): - self.content += chunk - - -class MarkupString(unicode): - """A simple class for dealing with marked up strings. When we are sliced, we return - valid marked up strings, preserving markup.""" - def __init__(self, string): - unicode.__init__(self) - self.handler = simpleHandler() - xml.sax.parseString((u"%s" % string).encode('utf-8'), self.handler) - self.raw = self.handler.content - - def __getitem__(self, n): - return self.__getslice__(n, n + 1) - - def __getslice__(self, s, e): - # only include relevant elements - if not e or e > len(self.raw): e = len(self.raw) - elements = filter(lambda tp: (tp[0][1] >= s and # end after the start... - tp[0][0] <= e # and start before the end - ), - self.handler.elements) - ends = {} - starts = {} - for el in elements: - # cycle through elements that effect our slice and keep track of - # where their start and end tags should go. - pos = el[0] - name = el[1] - attrs = el[2] - # write our start tag - stag = "<%s" % name - for k, v in attrs.items(): stag += " %s=%s" % (k, xml.sax.saxutils.quoteattr(v)) - stag += ">" - etag = "" % name # simple end tag - spos = pos[0] - epos = pos[1] - if spos < s: spos = s - if epos > e: epos = e - if epos != spos: # we don't care about tags that don't markup any text - if not starts.has_key(spos): starts[spos] = [] - starts[spos].append(stag) - if not ends.has_key(epos): ends[epos] = [] - ends[epos].append(etag) - outbuf = "" # our actual output string - for pos in range(s, e): # we move through positions - char = self.raw[pos] - if ends.has_key(pos): # if there are endtags to insert... - for et in ends[pos]: outbuf += et - if starts.has_key(pos): # if there are start tags to insert - mystarts = starts[pos] - # reverse these so the order works out,e.g. - mystarts.reverse() - for st in mystarts: outbuf += st - outbuf += char - if ends.has_key(e): - for et in ends[e]: outbuf += et - return MarkupString(outbuf) - - def __len__(self): - return len(self.raw) - diff --git a/wolnelektury/static/css/base.css b/wolnelektury/static/css/base.css index cd59f69a6..a89116abf 100755 --- a/wolnelektury/static/css/base.css +++ b/wolnelektury/static/css/base.css @@ -178,8 +178,7 @@ h2 { #footer { - color: #777; - eborder-top: 1px solid #ddd; + color: #767676; margin-top: 5em; padding-top:3em; background: #fff; diff --git a/wolnelektury/static/css/cite.css b/wolnelektury/static/css/cite.css index c86ea6504..4335f2ee6 100755 --- a/wolnelektury/static/css/cite.css +++ b/wolnelektury/static/css/cite.css @@ -4,16 +4,19 @@ a.cite { background: white; padding: 3em 2em .1em 8em; } -.cite-body { +.book-wide-box .cite-body, +#tagged-object-list .cite-body + { font-size: 1.8em; line-height: 1.3em; } -.cite p { +.book-wide-box .source, +#tagged-object-list .source +{ color: #444; font-size: 1.1em; margin-top: 1.6em; } - .cite .vip { margin: 0; color: #575C63; @@ -21,16 +24,27 @@ a.cite { } +/* a long cite displays smaller */ +.cite-small .cite-body span { + font-size: 1.4em; +} + #big-cite { - background-color: white; + background-color: #5f3e1c; /* average image color */ + color: white; padding: 0; margin: 0; + background-image: url(/static/img/backdrop/boltron-3212284622.jpg); + background-size: 100%; + background-position: 50% 50%; } #big-cite .cite { - padding: 10.75em 10em 8.5em 18.2em; + padding: 4.6em 4em 4.8em 0; + background: none; + color: white; } #big-cite h2 { @@ -41,23 +55,53 @@ a.cite { #big-cite .cite-body { - margin: .05em; - font-size: 2.8em; - line-height: 1.2em; - color: #191919; + margin: .05em .05em .05em 17.5em; +} +#big-cite .cite-body span { + font-size: 3em; + line-height: 1.16em; +} + +#big-cite .vip { + float:left; + text-align:right; + width: 14.7em; + margin-top: .25em; +} + +#big-cite .vip span { + font-size:1.1em; +} + +#big-cite .cite-body span, +#big-cite .vip span, +#big-cite .source span +{ + color: white; + background-color: rgb(0, 0, 0); + background-color: rgba(0, 0, 0, 0.6); + /* For IE 5.5 - 7*/ + filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000); + /* For IE 8*/ + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)"; +} +/* a long cite displays smaller */ +#big-cite .cite-small .cite-body span { + font-size: 2em; } #big-cite .source { - color: #00a1ac; - margin: 0; + margin: 1.6em 0.2em 1.6em 17.5em; +} +#big-cite .source span { font-size: 1.1em; - margin: 1.1em 0.2em; } + .cite blockquote p { margin: 0; } @@ -72,7 +116,7 @@ a.cite { top: -0.8em; right: -1em; background-color: #f7f7f7; - vertical-align: center; + vertical-align: middle; width: 39.5em; margin: 0; padding: 1em; diff --git a/wolnelektury/static/css/header.css b/wolnelektury/static/css/header.css index 9435ad7c0..f8cf7568b 100755 --- a/wolnelektury/static/css/header.css +++ b/wolnelektury/static/css/header.css @@ -27,6 +27,7 @@ #half-header-content { background: #191919; + color: #989898; } @@ -58,6 +59,7 @@ #search-area { margin: 0; background: #444; + color: white; margin-left: 24em; width: 73.5em; } @@ -108,6 +110,7 @@ #search-button { display: inline-block; background: #02adb7; + color: white; padding: 0; margin: 0; width: 9.4em; diff --git a/wolnelektury/static/img/backdrop/boltron-3212284622.jpg b/wolnelektury/static/img/backdrop/boltron-3212284622.jpg new file mode 100644 index 000000000..3fa342d8a Binary files /dev/null and b/wolnelektury/static/img/backdrop/boltron-3212284622.jpg differ diff --git a/wolnelektury/templates/catalogue/book_short.html b/wolnelektury/templates/catalogue/book_short.html index 9eae96fd8..383b1efa2 100644 --- a/wolnelektury/templates/catalogue/book_short.html +++ b/wolnelektury/templates/catalogue/book_short.html @@ -40,8 +40,7 @@ {% for name, slug in related.tags.author %} {{ name }}{% if not forloop.last %}, {% endif %}{% endfor %}{% for title, slug in related.parents %}, - {{ title }} - {% endfor %} + {{ title }}{% endfor %} @@ -72,8 +71,6 @@ - {% block book-box-extra-info %}{% endblock %} -
  • {% if book.html_file %} @@ -103,6 +100,7 @@ {% endif %}
+ {% block book-box-extra-info %}{% endblock %} {% block box-append %} {% endblock %}
diff --git a/wolnelektury/templates/catalogue/fragment_promo.html b/wolnelektury/templates/catalogue/fragment_promo.html index a3b01be16..cf817ae7c 100755 --- a/wolnelektury/templates/catalogue/fragment_promo.html +++ b/wolnelektury/templates/catalogue/fragment_promo.html @@ -1,10 +1,8 @@ -{% load removewholetags from catalogue_tags %} - {% if fragment %}
- {{ fragment.text|removewholetags:"a"|truncatewords_html:15|safe }} + {{ fragment.get_short_text|safe }}
-

{{ fragment.book.pretty_title }}

+

{{ fragment.book.pretty_title }}

{% endif %} diff --git a/wolnelektury/templates/main_page.html b/wolnelektury/templates/main_page.html index b4907129b..d2dc57b30 100755 --- a/wolnelektury/templates/main_page.html +++ b/wolnelektury/templates/main_page.html @@ -1,5 +1,5 @@ {% extends "base.html" %} -{% load cache i18n catalogue_tags infopages_tags social_tags %} +{% load cache chunks i18n catalogue_tags infopages_tags social_tags %} {% block title %}{% trans "Wolne Lektury internet library" %}{% endblock %} @@ -14,21 +14,12 @@
-
-

Trwa konkurs

-
-
-

Konkurs poezji automatycznej

-
-

Znacie Leśmianatora? To niewielki skrypt miskujący na życzenie - wiersze z Wolnych Lektur.

-
-
+ {% chunk "promo" %}

Ostatnie publikacje

- {% cache 300 last-published-on-main %} + {% cache 60 last-published-on-main %} {% for book in last_published %} {% book_mini book %} {% endfor %} @@ -77,3 +68,12 @@ {% endspaceless %} {% endblock %} + + +{% block add_footer %} +

{% trans "Image used:" %} +Everyone loves books…, +boltron-@Flickr, +CC BY-SA. +

+{% endblock %}