diff options
author | luxagraf <sng@luxagraf.net> | 2016-06-17 10:21:26 -0400 |
---|---|---|
committer | luxagraf <sng@luxagraf.net> | 2016-06-17 10:21:26 -0400 |
commit | b658d4b38f1aab3ed1bdc629300392c1b3e9e8fa (patch) | |
tree | 28eefd84cd586f23f1b1e7d96c4b58c229b7e183 | |
parent | cec274a4b7de8e07a3d7dc29127ba18f0dd42305 (diff) |
fixed notes to be like an instagram for the web also tweaked styles for
picwide captions and added support for show camera make, model and lens
-rw-r--r-- | app/jrnl/models.py | 12 | ||||
-rw-r--r-- | app/notes/admin.py | 3 | ||||
-rw-r--r-- | app/notes/migrations/0004_auto_20160616_1444.py | 27 | ||||
-rw-r--r-- | app/notes/migrations/0005_auto_20160616_1445.py | 20 | ||||
-rw-r--r-- | app/notes/models.py | 6 | ||||
-rw-r--r-- | app/photos/models.py | 2 | ||||
-rw-r--r-- | app/utils/views.py | 10 | ||||
-rw-r--r-- | config/base_urls.py | 3 | ||||
-rw-r--r-- | design/sass/_global.scss | 9 | ||||
-rw-r--r-- | design/sass/_notes.scss | 1 | ||||
-rw-r--r-- | design/sass/_writing_details.scss | 20 | ||||
-rw-r--r-- | design/templates/admin/insert_images.html | 108 | ||||
-rw-r--r-- | design/templates/admin/notes/change_form.html | 139 | ||||
-rw-r--r-- | design/templates/archives/notes.html | 5 | ||||
-rw-r--r-- | design/templates/lib/img_picwide.html | 4 |
15 files changed, 351 insertions, 18 deletions
diff --git a/app/jrnl/models.py b/app/jrnl/models.py index d19e39d..874da74 100644 --- a/app/jrnl/models.py +++ b/app/jrnl/models.py @@ -43,13 +43,23 @@ def parse_image(s): i = LuxImage.objects.get(image__icontains=src) cl = img['class'] caption = False + exif = False if len(cl) > 1: css_class = cl[0] if cl[1] == 'caption': caption = True + if cl[1] == 'exif': + exif = True + if len(cl) > 2: + css_class = cl[0] + if cl[1] == 'caption': + caption = True + if cl[2] == 'exif': + exif = True + print('caption'+str(caption)) else: css_class = cl[0] - c = Context({'image': i, 'caption': caption}) + c = Context({'image': i, 'caption': caption, 'exif': exif}) return render_to_string("lib/img_%s.html" % css_class, c) diff --git a/app/notes/admin.py b/app/notes/admin.py index 3e15be2..e84b7a0 100644 --- a/app/notes/admin.py +++ b/app/notes/admin.py @@ -2,11 +2,10 @@ from django.contrib import admin from django.contrib.gis.admin import OSMGeoAdmin from notes.models import Note, LuxNote -from utils.widgets import AdminImageWidget, LGEntryForm, LGEntryFormSmall, OLAdminBase +from utils.widgets import LGEntryForm, OLAdminBase class LuxNoteAdmin(OLAdminBase): - form = LGEntryFormSmall prepopulated_fields = {"slug": ('title',)} list_display = ('slug', 'pub_date', 'location') fieldsets = ( diff --git a/app/notes/migrations/0004_auto_20160616_1444.py b/app/notes/migrations/0004_auto_20160616_1444.py new file mode 100644 index 0000000..76b1f3a --- /dev/null +++ b/app/notes/migrations/0004_auto_20160616_1444.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-06-16 14:44 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('photos', '0010_auto_20160517_0906'), + ('notes', '0003_auto_20160208_1120'), + ] + + operations = [ + migrations.AddField( + model_name='luxnote', + name='images', + field=models.ManyToManyField(to='photos.LuxImage'), + ), + migrations.AlterField( + model_name='luxnote', + name='pub_date', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] diff --git a/app/notes/migrations/0005_auto_20160616_1445.py b/app/notes/migrations/0005_auto_20160616_1445.py new file mode 100644 index 0000000..129bbc2 --- /dev/null +++ b/app/notes/migrations/0005_auto_20160616_1445.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-06-16 14:45 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('notes', '0004_auto_20160616_1444'), + ] + + operations = [ + migrations.AlterField( + model_name='luxnote', + name='images', + field=models.ManyToManyField(blank=True, null=True, to='photos.LuxImage'), + ), + ] diff --git a/app/notes/models.py b/app/notes/models.py index 775c78c..1acf966 100644 --- a/app/notes/models.py +++ b/app/notes/models.py @@ -17,6 +17,8 @@ import markdown from utils.widgets import markdown_to_html from daily.models import CheckIn +from photos.models import LuxImage +from jrnl.models import render_images def twitter_truncate(txt): @@ -32,6 +34,7 @@ class LuxNote(models.Model): body_markdown = models.TextField('Note') point = models.PointField(blank=True, null=True) location = models.ForeignKey(Location, blank=True, null=True) + images = models.ManyToManyField(LuxImage, blank=True, null=True) def __str__(self): return self.title @@ -63,7 +66,8 @@ class LuxNote(models.Model): def save(self, *args, **kwargs): - self.body_html = markdown_to_html(self.body_markdown) + md = render_images(self.body_markdown) + self.body_html = markdown_to_html(md) if not self.point: self.point = CheckIn.objects.latest().point try: diff --git a/app/photos/models.py b/app/photos/models.py index 9ec68e0..e90a079 100644 --- a/app/photos/models.py +++ b/app/photos/models.py @@ -86,6 +86,8 @@ class LuxImage(models.Model): def get_image_by_size(self, size="original"): base = self.get_image_name() + if size == "admin_insert": + return "images/%s/%s.%s" % (self.pub_date.strftime("%Y"), base, self.get_image_ext()) if size == "original": return "%soriginal/%s/%s.%s" % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), base, self.get_image_ext()) else: diff --git a/app/utils/views.py b/app/utils/views.py index f28a8cd..b1decf6 100644 --- a/app/utils/views.py +++ b/app/utils/views.py @@ -1,5 +1,7 @@ from django.views.generic import ListView - +from photos.models import LuxImage +from django.shortcuts import render_to_response +from django.template import RequestContext class PaginatedListView(ListView): """ @@ -17,3 +19,9 @@ class PaginatedListView(ListView): print(request.page_url) request.page = int(self.kwargs['page']) return super(PaginatedListView, self).dispatch(request, *args, **kwargs) + + +def insert_image(request): + images = LuxImage.objects.all()[:50] + return render_to_response('admin/insert_images.html', {'images': images, 'textarea_id': request.GET['textarea']}, context_instance=RequestContext(request)) + diff --git a/config/base_urls.py b/config/base_urls.py index 4466cd6..9cc2186 100644 --- a/config/base_urls.py +++ b/config/base_urls.py @@ -16,7 +16,7 @@ from figments.models import FigmentSitemap from projects.models.base import ProjectSitemap from syndication.views import FacebookFeedView import builder.views - +import utils.views admin.autodiscover() @@ -39,6 +39,7 @@ urlpatterns += [ url(r'^autocomplete/', include('autocomplete_light.urls')), url(r'^admin/build/.*', builder.views.do_build), url(r'^admin/', include(admin.site.urls),), + url(r'^luximages/insert/', utils.views.insert_image), url(r'^sitemap.xml$', sitemap, {'sitemaps': sitemaps}), url(r'^links/', include('links.urls')), url(r'^jrnl/', include('jrnl.urls')), diff --git a/design/sass/_global.scss b/design/sass/_global.scss index 7e84f1f..27f731f 100644 --- a/design/sass/_global.scss +++ b/design/sass/_global.scss @@ -112,6 +112,15 @@ h1 { @include fontsize(11); } +.subhead { + font-style: italic; + font-weight: 400; + margin-top: 0; + @include constrain_narrow; + @include breakpoint(beta) { + text-align: left; + } +} .mailing-list--wrapper { @include constrain_narrow; @include breakpoint(gamma) { diff --git a/design/sass/_notes.scss b/design/sass/_notes.scss index 1a6d35d..1357668 100644 --- a/design/sass/_notes.scss +++ b/design/sass/_notes.scss @@ -12,7 +12,6 @@ } } } - .notes .h-entry { @extend %clearfix; border: none; diff --git a/design/sass/_writing_details.scss b/design/sass/_writing_details.scss index c34f0c3..c94fcaf 100644 --- a/design/sass/_writing_details.scss +++ b/design/sass/_writing_details.scss @@ -27,7 +27,7 @@ @include smcaps; @include fontsize(11); } -.post--article { +.post--article, .notes .h-entry { h2, h3 { @include constrain_narrow; font-family: Helvetica Neue, Helvetica, sans-serif; @@ -236,7 +236,7 @@ margin-left: auto; margin-right: auto; display: block; } -.picwide { +img.picwide { clear: both; margin: 1em 0; @include breakpoint(gamma) { @@ -250,6 +250,22 @@ display: block; max-width: 1170px; } } +.picwide figcaption { + margin-bottom: 2em; + border-bottom: 1px solid #eae6e6; + padding-bottom: .5em; + @include breakpoint(gamma) { + margin-left: -140px; + width: 960px; + max-width: 960px; + } + @include breakpoint(delta) { + margin-left: -245px; + margin-top: -10px; + width: 1170px; + max-width: 1170px; + } +} .picwide960 { clear: both; margin: 1em 0; diff --git a/design/templates/admin/insert_images.html b/design/templates/admin/insert_images.html new file mode 100644 index 0000000..7e39583 --- /dev/null +++ b/design/templates/admin/insert_images.html @@ -0,0 +1,108 @@ +{% load get_image_by_size %} +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<head> +<style> +.item-wrapper { + display: flex; + flex-wrap: wrap; + margin-bottom: 6px; + font-family: sans-serif; + font-size: 11px; + padding: 6px 0 4px; + border-top: #ccc 1px solid; +} +.item { margin: 0;} +.item img { margin: 0 0 4px 0;} +figure { + max-width: 180px; +} +.actions { + list-style-type: none; + margin: 0 0 0 10px; + padding: 0; +} +.actions li { + margin: 3px 0; +} +.actions a { + color: #666; +} +</style> +<script src="/static/jquery.tools.min.js"></script> +<script> +// execute your scripts when the DOM is ready. this is a good habit + +function buildImage(image_url, c, caption) { + html = '<img src="'+image_url+'" class="'; + if (c) { + html += c; + } + if (caption) { + html += ' caption" />'; + } + else { + html += '" />'; + } + return html; +} +$(function(){ + var ta = parent.document.getElementById('{{textarea_id}}'); + + $('#uploads li').click(function(){ + $(this).children('.popup').show(); + }); + + $('.popup .close').click(function(){ + $(this).parent('.popup').hide(); + return false; + }); + + $('.insert').click(function(){ + var code = buildImage($(this).attr('data-src'), $(this).attr('data-class'), $(this).attr('data-caption')); + var el = parent.document.getElementById('{{textarea_id}}'); + var start = el.selectionStart + var end = el.selectionEnd + var text = el.value + var before = text.substring(0, start) + var after = text.substring(end, text.length) + el.value = (before + code + after) + el.selectionStart = el.selectionEnd = start + code.length + el.focus() + $(this).parents('.popup').hide(); + return false; + }); + + $('#refresh').click(function(){ + location.reload(true); + return false; + }); + +}); + + +</script> +</head> +<body> + <input type="button" value="Refresh" onClick="window.location.reload()"> + <div class="up-wrapper">{% for image in images %} + <div class="item-wrapper"> + <figure class="item" > + <img src="{% get_image_by_size image 'tn' %}" /> + <figcaption>{{image.title}} {% if image.caption %}– {{image.caption}}{%endif%}</figcaption> + </figure> + <ul class="actions"> + <li><a data-src="{% get_image_by_size image 'admin_insert' %}" data-class="picwide" class="insert" href="">full width</a></li> + <li><a data-src="{% get_image_by_size image 'admin_insert' %}" data-class="picfull" class="insert" href="">column width</a></li> + <li><a data-src="{% get_image_by_size image 'admin_insert' %}" data-class="picwide" data-caption="true" class="insert" href="">full width cap</a></li> + <li><a data-src="{% get_image_by_size image 'admin_insert' %}" data-class="picfull" data-caption="true" class="insert" href="">column width cap</a></li> + <li><a href="/admin/photos/luximage/{{image.pk}}/change/">Edit Image</a></li> + </ul> + </div> +{% endfor %} +</div> + +<!-- "next page" action --> +<a class="nextPage browse right"></a> +</body> +</html> diff --git a/design/templates/admin/notes/change_form.html b/design/templates/admin/notes/change_form.html index 3d97a4f..56d2bbe 100644 --- a/design/templates/admin/notes/change_form.html +++ b/design/templates/admin/notes/change_form.html @@ -1,10 +1,48 @@ -{% extends "admin/change_form.html" %} -{% load i18n admin_urls %} +{% extends "admin/base_site.html" %} +{% load i18n admin_urls admin_static admin_modify %} + +{% block extrahead %}{{ block.super }} +<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script> +{{ media }} +<script> +if (!$) { + $ = django.jQuery; +} +$(function(){ + $('#id_body_markdown').each(function(){ + $(this).css('width', '550px').css('height', '300px'); + $(this).after('<iframe frameborder="0" style="border: #dddddd 1px solid;margin-left: 20px;width:330px; height:310px;" src="/luximages/insert/?textarea='+this.id+'"></iframe>'); + }); +}); +</script> + +{% endblock %} + +{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %} + +{% block coltype %}colM{% endblock %} + +{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-form{% endblock %} + +{% if not is_popup %} +{% block breadcrumbs %} +<div class="breadcrumbs"> +<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a> +› <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a> +› {% if has_change_permission %}<a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %} +› {% if add %}{% trans 'Add' %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %} +</div> +{% endblock %} +{% endif %} + {% block content %} <a class="btn" onclick="geoFindMe();" href="javascript:void(0);" class="historylink">Get Location</a> - {{block.super}} -{% endblock %} -{% block object-tools-items %} +<div id="content-main"> +{% block object-tools %} +{% if change %}{% if not is_popup %} + <ul class="object-tools"> + {% block object-tools-items %} + <li> <a onclick="geoFindMe();" href="javascript:void(0);" class="historylink">Get Location</a> </li> @@ -16,4 +54,95 @@ <a href="{% url 'admin:view_on_site' content_type_id original.pk %}" class="viewsitelink">{% trans "View on site" %}</a> </li> {% endif %} + <li> + {% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %} + <a href="{% add_preserved_filters history_url %}" class="historylink">{% trans "History" %}</a> + </li> + {% if has_absolute_url %}<li><a href="{{ absolute_url }}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif %} + {% endblock %} + </ul> +{% endif %}{% endif %} +{% endblock %} +<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.model_name }}_form" novalidate>{% csrf_token %}{% block form_top %}{% endblock %} +<div> +{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %} +{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %} +{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %} +{% if errors %} + <p class="errornote"> + {% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %} + </p> + {{ adminform.form.non_field_errors }} +{% endif %} + +{% block field_sets %} +{% for fieldset in adminform %} + {% include "admin/includes/fieldset.html" %} +{% endfor %} +{% endblock %} + +{% block after_field_sets %}{% endblock %} + +{% block inline_field_sets %} +{% for inline_admin_formset in inline_admin_formsets %} + {% include inline_admin_formset.opts.template %} +{% endfor %} +{% endblock %} + +{% block after_related_objects %}{% endblock %} + +{% block submit_buttons_bottom %}{% submit_row %}{% endblock %} + +{% block admin_change_form_document_ready %} + <script type="text/javascript"> + (function($) { + $(document).ready(function() { + $('.add-another').click(function(e) { + e.preventDefault(); + var event = $.Event('django:add-another-related'); + $(this).trigger(event); + if (!event.isDefaultPrevented()) { + showAddAnotherPopup(this); + } + }); + $('.related-lookup').click(function(e) { + e.preventDefault(); + var event = $.Event('django:lookup-related'); + $(this).trigger(event); + if (!event.isDefaultPrevented()) { + showRelatedObjectLookupPopup(this); + } + }); + $('body').on('click', '.related-widget-wrapper-link', function(e) { + e.preventDefault(); + if (this.href) { + var event = $.Event('django:show-related', {href: this.href}); + $(this).trigger(event); + if (!event.isDefaultPrevented()) { + showRelatedObjectPopup(this); + } + } + }); + $('body').on('change', '.related-widget-wrapper select', function(e) { + var event = $.Event('django:update-related'); + $(this).trigger(event); + if (!event.isDefaultPrevented()) { + updateRelatedObjectLinks(this); + } + }); + $('.related-widget-wrapper select').trigger('change'); + + {% if adminform and add %} + $('form#{{ opts.model_name }}_form :input:visible:enabled:first').focus() + {% endif %} + }); + })(django.jQuery); + </script> +{% endblock %} + +{# JavaScript for prepopulated fields #} +{% prepopulated_fields_js %} + +</div> +</form></div> {% endblock %} diff --git a/design/templates/archives/notes.html b/design/templates/archives/notes.html index 9429831..4e8b105 100644 --- a/design/templates/archives/notes.html +++ b/design/templates/archives/notes.html @@ -12,11 +12,12 @@ </ul> <main role="main"> <h1>Field Notes</h1> + <h4 class="subhead divide-after">Quick notes and images from the road</h4> {% for object in object_list %} <article class="h-entry"> - <h2 class="p-name note--title">{{object.title|safe|amp|smartypants}}</h2> + <h2 class="p-name note--title hide">{{object.title|safe|amp|smartypants}}</h2> <div class="e-content"> - {{object.body_html|safe|amp|smartypants|urlizetrunc:45 }} + {{object.body_html|safe|smartypants}} </div> <span class="p-author h-card"> <data class="p-name" value="Scott Gilbertson"></data> diff --git a/design/templates/lib/img_picwide.html b/design/templates/lib/img_picwide.html index 065ff6c..be2b779 100644 --- a/design/templates/lib/img_picwide.html +++ b/design/templates/lib/img_picwide.html @@ -1,9 +1,9 @@ {% load get_image_by_size %} -{% if caption %} +{% if caption or exif %} <figure class="picwide">{%endif%} <img class="picwide" sizes="(max-width: 1140px) 100vw, (min-width: 1141px) 1140px" srcset="{% for size in image.sizes.all%}{% get_image_by_size image size %} {{size}}w{% if forloop.last%}"{%else%}, {%endif%}{%endfor%} {% for size in image.sizes.all%}{%if not forloop.first and not forloop.last%}src="{% get_image_by_size image size %}"{%endif%}{%endfor%} alt="{{image.alt}} photographed by {% if image.photo_credit_source %}{{image.photo_credit_source}}{%else%}luxagraf{%endif%}"> - {% if caption %}<figcaption>{{image.caption}}</figcaption> +{% if caption or exif %}<figcaption>{% endif %}{% if caption %}{{image.caption}}{% endif %}{% if exif %} | <small>Camera: {{image.exif_make}} {{image.exif_model}} with {{image.exif_lens}}</small>{% endif %}{% if caption or exif %}</figcaption> </figure> {% endif %} |