diff options
author | luxagraf <sng@luxagraf.net> | 2015-10-15 21:01:17 -0400 |
---|---|---|
committer | luxagraf <sng@luxagraf.net> | 2015-10-15 21:01:17 -0400 |
commit | 954830a51fa906c6b16941fd39675c8439ba7351 (patch) | |
tree | 12da95f31959f73eb8faa1766339cf21955fe659 | |
parent | e0de7a6c08bbbd31fae2e7b796457a982cb3e895 (diff) |
polished up the books section a bit
-rw-r--r-- | app/books/admin.py | 2 | ||||
-rw-r--r-- | app/books/models.py | 9 | ||||
-rw-r--r-- | app/books/views.py | 15 | ||||
-rw-r--r-- | design/sass/_books.scss | 122 | ||||
-rw-r--r-- | design/sass/_queries.scss | 10 | ||||
-rw-r--r-- | design/templates/archives/books.html | 31 | ||||
-rw-r--r-- | design/templates/details/book.html | 14 |
7 files changed, 168 insertions, 35 deletions
diff --git a/app/books/admin.py b/app/books/admin.py index 6ba03ff..83ccf93 100644 --- a/app/books/admin.py +++ b/app/books/admin.py @@ -3,7 +3,7 @@ from .models import Book, BookHighlight class BookAdmin(admin.ModelAdmin): - list_display = ('title', 'admin_thumbnail', 'isbn', 'author_name', 'read_date') + list_display = ('title', 'admin_thumbnail', 'isbn', 'author_name', 'read_date', 'publish_date', 'openlib_url') class BookHighlightAdmin(admin.ModelAdmin): diff --git a/app/books/models.py b/app/books/models.py index 14c7160..f31edce 100644 --- a/app/books/models.py +++ b/app/books/models.py @@ -4,19 +4,19 @@ from django.conf import settings from django.template.defaultfilters import slugify from taggit.managers import TaggableManager +# http://freewisdom.org/projects/python-markdown/ import markdown class Book(models.Model): title = models.CharField(max_length=200) author_name = models.CharField(max_length=200) slug = models.CharField(max_length=50) - year_pub = models.CharField(max_length=4, blank=True, null=True) read_date = models.DateTimeField() isbn = models.CharField(max_length=100, blank=True, null=True) + body_markdown = models.TextField(null=True, blank=True) body_html = models.TextField(null=True, blank=True) read_in = models.TextField(null=True, blank=True) url = models.CharField(max_length=200, blank=True, null=True) - tags = TaggableManager() pages = models.CharField(max_length=5, blank=True, null=True) publish_date = models.CharField(max_length=40, blank=True, null=True) publish_place = models.CharField(max_length=100, blank=True, null=True) @@ -44,12 +44,17 @@ class Book(models.Model): def get_image_url(self): return '%sbook-covers/%s.jpg' % (settings.IMAGES_URL, self.slug) + def get_rating (self): + return int(self.rating) + def admin_thumbnail(self): return force_text('<a href=""><img src="%s" width="100" style="width:100px"></a>' % (self.get_image_url())) admin_thumbnail.allow_tags = True admin_thumbnail.short_description = 'Thumbnail' def save(self, *args, **kwargs): + if self.body_markdown: + self.body_html = markdown.markdown(self.body_markdown, extensions=['extra'], safe_mode=False) self.slug = slugify(self.title[:50]) super(Book, self).save() diff --git a/app/books/views.py b/app/books/views.py index 7809f17..21f271f 100644 --- a/app/books/views.py +++ b/app/books/views.py @@ -11,22 +11,27 @@ from photos.models import Photo def book_detail(request, slug): - obj = get_object_or_404(Book, slug__exact=slug) - return render_to_response('details/book.html', {'object': obj}, context_instance=RequestContext(request)) + context = { + 'object': get_object_or_404(Book, slug__exact=slug), + 'ratings_range' : range(1, 6) + } + return render_to_response('details/book.html', context, context_instance=RequestContext(request)) def book_list(request, page): - request.page_url = '/book/%d/' + request.page_url = '/books/%d/' request.page = int(page) try: is_build = request.POST['builder'] extra_context={ 'page':page, - 'MEDIA_URL': settings.BAKED_MEDIA_URL + 'MEDIA_URL': settings.BAKED_MEDIA_URL, + 'ratings_range': range(1, 6) } except: extra_context={'page':page} context = { 'object_list': Book.objects.order_by('-read_date').select_related(), - 'page': page + 'page': page, + 'ratings_range' : range(1, 6) } return render_to_response("archives/books.html", context, context_instance=RequestContext(request)) diff --git a/design/sass/_books.scss b/design/sass/_books.scss index 3ed8e2e..ec81b7e 100644 --- a/design/sass/_books.scss +++ b/design/sass/_books.scss @@ -1,3 +1,80 @@ +.book-list { + @extend %clearfix; + @include constrain_wide; +} + +.book-list-item { + margin: 2em 0; + h2 { + text-align: left; + margin: .25rem 4px; + font-weight: normal; + @include fontsize(24); + line-height: 1.2; + a { + color: $body_font; + text-decoration: none; + font-style: italic; + } + @include breakpoint(gamma) { + @include fontsize(22); + margin: .1rem 4px; + } + } + h4, { + @include fontsize(12); + @include smcaps; + font-weight: normal; + margin-top: 0; + margin-bottom: 0; + &:before { + content: "by " + } + } + @include breakpoint(alpha-2) { + text-align: left; + width: 45%; + float: left; + margin-right: 30px; + margin-top: 1em; + min-height: 500px; + .img-wrapper { + min-height: 350px; + } + } + @include breakpoint(gamma) { + width: 31%; + height: 650px; + float: left; + margin-right: 30px; + .img-wrapper { + min-height: 400px; + } + } + @include breakpoint(delta) { + width: 22%; + height: 550px; + } +} +.book-list .even { + @include breakpoint(alpha-2) { + margin-right: 0; + } + @include breakpoint(gamma) { + margin-right: 30px; + } +} +.book-list .tres { + @include breakpoint(gamma) { + margin-right: 0; + } + @include breakpoint(delta) { + margin-right: 30px; + } +} +.book-stars { + display: block; +} .book { margin-top: 2em; @include breakpoint(gamma) { @@ -14,7 +91,6 @@ } } .book-metadata { - @extend %clearfix; text-align: left; dd { display: inline; @@ -30,27 +106,65 @@ dt:after { content: ":"; } + @include breakpoint(gamma) { + margin-left: 80px; + } } .book-title { - @include constrain_narrow; + @include constrain_wide; line-height: 1.3; + @include breakpoint(gamma) { + max-width: 660px; + text-align: left; + position: relative; + left: 150px; + } + @include breakpoint(delta) { + left: 165px; + max-width: 850px; + } } -.book-cover { +.book-cover-wrapper { + @include breakpoint(gamma) { + display: block; + @include constrain_wide; + img { + float: left; + width: 250px; + margin-right: 32px; + } + } + @include breakpoint(delta) { + img { + max-width: 250px; + } + } } .thoughts, .highlights, .meta-cover { @include constrain_narrow; text-align: left; p { max-width: 100%; + @include breakpoint(gamma) { + margin-left: 80px; + } } } -.thoughts h5, .highlights h4, .meta-cover h5 { +.meta-cover { +} +.thoughts h5, .highlights h4 { font-weight: 500; letter-spacing: 1px; margin: 3em 0 .5em 0; @include generic_sans; @include smcaps; @include fontsize(14); + @include breakpoint(gamma) { + margin-left: 80px; + } +} +.highlights article:first-of-type { + margin-top: 1em; } .highlights .foot { @include fontsize(14); diff --git a/design/sass/_queries.scss b/design/sass/_queries.scss index 1d7f3ef..8262c84 100644 --- a/design/sass/_queries.scss +++ b/design/sass/_queries.scss @@ -1,6 +1,7 @@ $breakpoint-alpha: 38em; +$breakpoint-alpha-2: 450px; $breakpoint-beta: 49em; -$breakpoint-book-beta: 620px; +$breakpoint-beta-2: 620px; $breakpoint-gamma: 56em; $breakpoint-delta: 73.125em; $breakpoint-epsilon: 79.625em; @@ -9,11 +10,14 @@ $breakpoint-epsilon: 79.625em; @if $point == "alpha" { @media screen and (min-width:$breakpoint-alpha ){ @content; } } + @if $point == "alpha-2" { + @media screen and (min-width:$breakpoint-alpha-2 ){ @content; } + } @else if $point == "beta" { @media screen and (min-width: $breakpoint-beta) { @content; } } - @else if $point == "book-beta" { - @media screen and (min-width: $breakpoint-book-beta) { @content; } + @else if $point == "beta-2" { + @media screen and (min-width: $breakpoint-beta-2) { @content; } } @else if $point == "gamma" { @media screen and (min-width: $breakpoint-gamma) { @content; } diff --git a/design/templates/archives/books.html b/design/templates/archives/books.html index f462a3a..980a4b7 100644 --- a/design/templates/archives/books.html +++ b/design/templates/archives/books.html @@ -3,7 +3,7 @@ {% load html5_datetime %} {% load pagination_tags %} {% block pagetitle %} Books | luxagraf {% endblock %} -{% block metadescription %}Books and thoughts on them. {% endblock %} +{% block metadescription %}Books I've read and thoughts on them. {% endblock %} {%block bodyid%}class="books" id="books-archive"{%endblock%} {% block primary %} @@ -11,24 +11,27 @@ <li><a href="/" title="luxagraf homepage" itemprop="url"><span itemprop="title">Home</span></a> → </li> <li>Books</li> </ul> - <main role="main"> - <h1>Books</h1> + <main role="main">{% autopaginate object_list 24 %} + <h1 class="hide">Books</h1> +<div class="book-list projects--intro"> <p>I wear glasses because as a child I would stay up late, covers pulled over my head, reading by the dim light of a dying flashlight. At least that's what an eye doctor told me when I was younger. Probably a load of crap, but I still love reading and I still often do it by poor light far later in the night than is reasonable.</p> - <p>A few years ago, I realized I was forgetting the things I'd read. Forgetting the things they had made me think of, things I'd learned, bits I wanted to remember. So I started taking notes while reading, usually with a pen and paper, but sometimes just photographing a page and using OCR to save it to a text file. I wanted to remember, to recall.</p> - <p>And of course since I have all this stuff in text files I thought might as well put it online. Thanks to some APIs out there it isn't hard to get all the info you need about a book. And well, here you have it, books I've read and things I've thought about them.</p> - {% autopaginate object_list 24 %}{% for object in object_list %} - <article itemscope itemtype="http://schema.org/Book"> - {% if object.image %}<img itemprop="image" src="{{object.get_image_url}}" alt="cover art: red horse, city in background"/>{%endif%} - <h2 itemprop="name"><a href="{{object.get_absolute_url}}">{{object.title|safe|amp|smartypants}}</a></h2> + <p>I've always taken notes while reading, usually with a pen and paper, but sometimes as highlights in the Kindle. And of course since I have all this stuff in text files I thought might as well put it online. So here you have it, books I've read and things I've thought about them.</p> +</div> + <nav class="pagination">{% paginate %} + </nav> + <div class="book-list"> {% for object in object_list %} + <article class="book-list-item {% cycle "odd" "even" %} {% cycle "uno" "dos" "tres" %}" itemscope itemtype="http://schema.org/Book"> + {% if object.image %}<div class="img-wrapper"><a href="{{object.get_absolute_url}}"><img itemprop="image" src="{{object.get_image_url}}" alt="cover art for {{object.title}} by {{object.author_name}}"/></a></div>{%endif%} + <h2 itemprop="name"><a href="{{object.get_absolute_url}}">{{object.title|amp|smartypants|widont|safe}}</a></h2> <h4 itemprop="author">{{object.author_name}}</h4> - <span itemprop="isbn">{{object.isbn}}</span> <div itemprop="review" itemscope itemtype="http://schema.org/Review"> - {% if object.rating %}<span itemprop="reviewRating">{{object.rating}}</span>stars{%endif%} + {% if object.rating %}<span class="book-stars" itemprop="reviewRating">{% for i in ratings_range %}{% if i <= object.get_rating%}★{%else%}☆{%endif%}{%endfor%}</span>{%endif%} <span class="hide" itemprop="author">Scott Gilbertson</span> - <meta itemprop="datePublished" content="{{object.read_date|date:'F Y'}}"><span>Read in: {{object.read_date|date:"F Y"}}</span> - <div itemprop="reviewBody">{{object.body_html|safe|amp|smartypants|urlizetrunc:45 }}</div> + <meta itemprop="datePublished" content="{{object.read_date|date:'F Y'}}"><span class="read-in">Read in: {{object.read_date|date:"F Y"}}</span></div> </article> -{% endfor %} + {% endfor %}</div> + <nav class="pagination">{% paginate %} + </nav> </main> {% endblock %} diff --git a/design/templates/details/book.html b/design/templates/details/book.html index 46ac10b..6524885 100644 --- a/design/templates/details/book.html +++ b/design/templates/details/book.html @@ -3,22 +3,24 @@ {%block bodyid%}id="book-page"{%endblock%} {% block primary %}<ul class="bl" id="breadcrumbs" itemscope itemtype="http://data-vocabulary.org/Breadcrumb"> <li><a href="/" title="luxagraf homepage" itemprop="url"><span itemprop="title">Home</span></a> → </li> - <li>Readings</li> + <li><a href="/books/" title="books" itemprop="url"><span itemprop="title">books</span></a> → </li> </ul> <main role="main" itemprop="mainEntity" itemscope itemtype="http://schema.org/Book"> <h1 class="book-title" itemprop="name">{{object.title|smartypants|widont|safe}}</h1> + <div class="book-cover-wrapper"><img src="{{object.get_image_url}}" alt="{{object.title}} cover" /></div> <div class="meta-cover"> - <img src="{{object.get_image_url}}" alt="{{object.title}} cover" class="book-cover" /> - <h5>Meta</h5> <dl class="book-metadata"> <dt>Author</dt> - <dd>{{object.author_name}}<dd> - {% if object.publish_place %}<dt>Published</dt> - <dd>{{object.publish_place}}{%endif%}{%if object.publish_date%}, {{object.publish_date}}</dd>{%endif%} + <dd>{{object.author_name}}</dd> + {% if object.publish_date %}<dt>Published</dt> + <dd>{%if object.publish_place%}{{object.publish_place}}, {%endif%}{{object.publish_date}}</dd>{%endif%} {% if object.pages %}<dt>Pages</dt> <dd>{{object.pages}}</dd>{%endif%} {% if object.isbn %}<dt>ISBN</dt> <dd>{{object.isbn}}</dd>{%endif%} + {% if object.isbn %}<dt>Borrow</dt> + <dd><a href="http://worldcat.org/isbn/{{object.isbn}}" title="find {{object.title}} in your local library">WorldCat</a></dd>{%endif%} + {% if object.rating %}<dt>Rating</dt><dd class="book-stars" itemprop="reviewRating"> {% for i in ratings_range %}{% if i <= object.get_rating%}★{%else%}☆{%endif%}{%endfor%}</dd>{%endif%} {% if object.read_in %}<dt>Read</dt> <dd>{{object.read_in}}</dd>{%endif%} </dl> |