Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

closing some display bugs, slug bug #117

Merged
merged 10 commits into from
This page is out of date. Refresh to see the latest.
View
29 media/css/app.css
@@ -198,6 +198,11 @@ article, .container {
line-height: 1.8em;
}
+article .article-block {
+ margin-bottom: 0;
+ overflow: hidden;
+}
+
h1, h2, h3, h5, h6, ul, ol, .caption, label {
font-family: 'Open Sans', Helvetica, sans-serif;
font-weight: 400;
@@ -492,10 +497,9 @@ h1.maintopic {
}
.image-inset-left-wrapper img, .image-inset-right-wrapper img {
- width: 300px;
+ width: 298px;
}
-img.map-inset-right,
img.list-thumbnail,
.image-full-width-wrapper img,
.image-inset-left-wrapper img,
@@ -509,11 +513,6 @@ img.list-thumbnail {
margin: 0 .67em .25em 0;
}
-.map-inset-right {
- width: 300px;
- height: 250px;
-}
-
.small, .link-list li i.small {
font-size: 0.8em;
}
@@ -1055,7 +1054,7 @@ img#main-logo {
font-size: .9em;
}
- img.map-inset-right {
+ img.map-inset {
display: none;
}
@@ -1068,5 +1067,19 @@ img#main-logo {
.search-form input[type="text"] {
width: auto;
}
+
+ .image-inset-left-wrapper,
+ .image-inset-right-wrapper {
+ float: none;
+ width: auto;
+ margin: .33em 0 1em;
+ }
}
+
+@media screen and (max-width: 480px) {
+ .image-inset-left-wrapper img,
+ .image-inset-right-wrapper img {
+ width: 98%;
+ }
+}
View
135 source/articles/migrations/0005_auto__del_unique_articleblock_slug.py
@@ -0,0 +1,135 @@
+# -*- coding: 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):
+ # Removing unique constraint on 'ArticleBlock', fields ['slug']
+ db.delete_unique('articles_articleblock', ['slug'])
+
+
+ def backwards(self, orm):
+ # Adding unique constraint on 'ArticleBlock', fields ['slug']
+ db.create_unique('articles_articleblock', ['slug'])
+
+
+ models = {
+ 'articles.article': {
+ 'Meta': {'ordering': "('-pubdate', 'title')", 'object_name': 'Article'},
+ 'article_type': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
+ 'authors': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'article_authors'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['people.Person']"}),
+ 'body': ('django.db.models.fields.TextField', [], {}),
+ 'code': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['code.Code']", 'null': 'True', 'blank': 'True'}),
+ 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'image': ('sorl.thumbnail.fields.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'image_caption': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'image_credit': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
+ 'is_live': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'organizations': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['people.Organization']", 'null': 'True', 'blank': 'True'}),
+ 'people': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['people.Person']", 'null': 'True', 'blank': 'True'}),
+ 'pubdate': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+ 'subhead': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'summary': ('django.db.models.fields.TextField', [], {}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '128'})
+ },
+ 'articles.articleblock': {
+ 'Meta': {'ordering': "('article', 'order', 'title')", 'object_name': 'ArticleBlock'},
+ 'article': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['articles.Article']"}),
+ 'body': ('django.db.models.fields.TextField', [], {}),
+ 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'image': ('sorl.thumbnail.fields.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'image_caption': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'image_credit': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
+ 'image_presentation': ('django.db.models.fields.CharField', [], {'max_length': '24', 'blank': 'True'}),
+ 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '128'})
+ },
+ 'code.code': {
+ 'Meta': {'ordering': "('slug',)", 'object_name': 'Code'},
+ 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_live': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'organizations': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['people.Organization']", 'null': 'True', 'blank': 'True'}),
+ 'people': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['people.Person']", 'null': 'True', 'blank': 'True'}),
+ 'repo_description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'repo_forks': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'repo_last_push': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'repo_watchers': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'screenshot': ('sorl.thumbnail.fields.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'seeking_contributors': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+ 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'people.organization': {
+ 'Meta': {'ordering': "('name',)", 'object_name': 'Organization'},
+ 'address': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'city': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
+ 'country': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
+ 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'github_username': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
+ 'homepage': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_live': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'logo': ('sorl.thumbnail.fields.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'show_in_lists': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+ 'state': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
+ 'twitter_username': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'})
+ },
+ 'people.person': {
+ 'Meta': {'ordering': "('last_name', 'first_name')", 'object_name': 'Person'},
+ 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'github_username': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_live': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'organizations': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['people.Organization']", 'null': 'True', 'blank': 'True'}),
+ 'show_in_lists': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+ 'twitter_username': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'})
+ },
+ 'taggit.tag': {
+ 'Meta': {'object_name': 'Tag'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
+ },
+ 'taggit.taggeditem': {
+ 'Meta': {'object_name': 'TaggedItem'},
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_tagged_items'", 'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+ 'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_items'", 'to': "orm['taggit.Tag']"})
+ }
+ }
+
+ complete_apps = ['articles']
View
2  source/articles/models.py
@@ -95,7 +95,7 @@ class ArticleBlock(CachingMixin, models.Model):
modified = models.DateTimeField(auto_now=True)
article = models.ForeignKey(Article)
title = models.CharField(max_length=128)
- slug = models.SlugField(unique=True)
+ slug = models.SlugField()
order = models.PositiveIntegerField(default=1)
image = ImageField(upload_to='img/uploads/article_images', blank=True, null=True)
image_presentation = models.CharField(max_length=24, choices=IMAGE_PRESENTATION_CHOICES, blank=True)
View
2  source/articles/templates/articles/_base_articles.html
@@ -1,3 +1,3 @@
{% extends "base.html" %}
{% set active_nav = "features" %}
-{% block page_title %}Features{% if tag %} / {{ tag.name }}{% endif %} - {{ super() }}{% endblock %}
+{% block page_title %}Features{% if tags %} tagged: {% for tag in tags %}{{ tag.name }}{% if not loop.last %}, {% endif %}{% endfor %}{% endif %} - {{ super() }}{% endblock %}
View
2  source/articles/templates/articles/article_detail.html
@@ -44,7 +44,7 @@ <h6 class="date">{{ article.pretty_pubdate }}</h6>
{{ article.body|linebreaks|safe }}
{% for articleblock in article.articleblock_set.all() %}
- <div class="page-block">
+ <div class="page-block article-block">
<h3 id="{{ articleblock.slug }}">{{ articleblock.title }}</h3>
{% if articleblock.image and articleblock.image_presentation in ['full-width','inset-left','inset-right'] %}
{% set _image_width_options = {
View
2  source/articles/templates/articles/article_list.html
@@ -2,7 +2,7 @@
{% block content %}
{% if section %}
-<h1 class="maintopic"><a href="{{ url('article_list_by_section', section.slug) }}">{{ section.name }}</a>{% if category %} / <span class="category">{{ category }}</span>{% endif %}{% if tag %} / <span class="category">{{ tag.name }}</span>{% endif %}</h1>
+<h1 class="maintopic"><a href="{{ url('article_list_by_section', section.slug) }}">{{ section.name }}</a>{% if category %} / <span class="category">{{ category }}</span>{% endif %}{% if tags %} / <span class="category">{% for tag in tags %}{{ tag.name }}{% if not loop.last %}, {% endif %}{% endfor %}</span>{% endif %}</h1>
{% endif %}
{% for article in page.object_list %}
View
4 source/articles/urls.py
@@ -15,13 +15,13 @@
# name = 'article_list',
#,
url(
- regex = '^tags/(?P<tag_slug>[-\w]+)/$',
+ regex = '^tags/(?P<tag_slugs>[-\w\+]+)/$',
view = ArticleList.as_view(),
kwargs = {},
name = 'article_list_by_tag',
),
url(
- regex = '^tags/(?P<tag_slug>[-\w]+)/rss/$',
+ regex = '^tags/(?P<tag_slugs>[-\w\+]+)/rss/$',
view = cache_page(ArticleFeed(), 60*15),
kwargs = {},
name = 'article_list_by_tag_feed',
View
21 source/articles/views.py
@@ -67,9 +67,9 @@ class ArticleList(ListView):
def dispatch(self, *args, **kwargs):
self.section = kwargs.get('section', None)
self.category = kwargs.get('category', None)
- self.tag_slug = kwargs.get('tag_slug', None)
- self.tag = None
-
+ self.tags = None
+ self.tag_slugs = kwargs.get('tag_slugs', None)
+ self.tag_slug_list = []
return super(ArticleList, self).dispatch(*args, **kwargs)
def get_queryset(self):
@@ -79,9 +79,12 @@ def get_queryset(self):
queryset = queryset.filter(article_type__in=SECTION_MAP[self.section]['article_types'])
elif self.category:
queryset = queryset.filter(article_type=self.category)
- elif self.tag_slug:
- self.tag = get_object_or_404(Tag, slug=self.kwargs['tag_slug'])
- queryset = queryset.filter(tags__slug=self.kwargs['tag_slug'])
+ elif self.tag_slugs:
+ self.tag_slug_list = self.tag_slugs.split('+')
+ # need to fail if any item in slug list references nonexistent tag
+ self.tags = [get_object_or_404(Tag, slug=tag_slug) for tag_slug in self.tag_slug_list]
+ for tag_slug in self.tag_slug_list:
+ queryset = queryset.filter(tags__slug=tag_slug)
return queryset
@@ -99,12 +102,12 @@ def get_section_links(self, context):
'active_nav': CATEGORY_MAP[self.category]['parent_slug'],
'rss_link': reverse('article_list_by_category_feed', kwargs={'category': self.category}),
})
- elif self.tag:
+ elif self.tags:
context.update({
'section': SECTION_MAP['articles'],
'active_nav': SECTION_MAP['articles']['slug'],
- 'tag':self.tag,
- 'rss_link': reverse('article_list_by_tag_feed', kwargs={'tag_slug': self.tag_slug}),
+ 'tags':self.tags,
+ 'rss_link': reverse('article_list_by_tag_feed', kwargs={'tag_slugs': self.tag_slugs}),
})
else:
context.update({
View
53 source/base/feeds.py
@@ -11,9 +11,13 @@ class ArticleFeed(Feed):
def get_object(self, request, *args, **kwargs):
self.section = kwargs.get('section', None)
self.category = kwargs.get('category', None)
- self.tag_slug = kwargs.get('tag_slug', None)
- if self.tag_slug:
- self.tag = get_object_or_404(Tag, slug=self.tag_slug)
+ self.tags = None
+ self.tag_slugs = kwargs.get('tag_slugs', None)
+ self.tag_slug_list = []
+ if self.tag_slugs:
+ self.tag_slug_list = self.tag_slugs.split('+')
+ # need to fail if any item in slug list references nonexistent tag
+ self.tags = [get_object_or_404(Tag, slug=tag_slug) for tag_slug in self.tag_slug_list]
return ''
def title(self, obj):
@@ -21,8 +25,8 @@ def title(self, obj):
return "Source: %s" % SECTION_MAP[self.section]['name']
elif self.category:
return "Source: Articles in the category %s" % CATEGORY_MAP[self.category]['name']
- elif self.tag_slug:
- return "Source: Articles tagged with '%s'" % self.tag.name
+ elif self.tag_slugs:
+ return "Source: Articles tagged with '%s'" % "+".join([tag.name for tag in self.tags])
return "Source"
def link(self, obj):
@@ -30,8 +34,8 @@ def link(self, obj):
return reverse('article_list_by_section', kwargs={'section': self.section})
elif self.category:
return reverse('article_list_by_category', kwargs={'category': self.category})
- elif self.tag_slug:
- return reverse('article_list_by_tag', kwargs={'tag_slug': self.tag_slug})
+ elif self.tag_slugs:
+ return reverse('article_list_by_tag', kwargs={'tag_slugs': self.tag_slugs})
return reverse('homepage')
def description(self, obj):
@@ -40,8 +44,8 @@ def description(self, obj):
identifier = "in the %s section" % SECTION_MAP[self.section]['name']
elif self.category:
identifier = "in the %s category" % CATEGORY_MAP[self.category]['name']
- elif self.tag_slug:
- identifier = "tagged with '%s'" % self.tag.name
+ elif self.tag_slugs:
+ identifier = "tagged with '%s'" % "+".join([tag.name for tag in self.tags])
return "Recent articles %s" % identifier
def item_title(self, item):
@@ -56,32 +60,37 @@ def items(self, obj):
queryset = queryset.filter(article_type__in=SECTION_MAP[self.section]['article_types'])
elif self.category:
queryset = queryset.filter(article_type=self.category)
- elif self.tag_slug:
- queryset = queryset.filter(tags__slug=self.tag_slug)
+ elif self.tag_slugs:
+ for tag_slug in self.tag_slug_list:
+ queryset = queryset.filter(tags__slug=tag_slug)
return queryset[:20]
class CodeFeed(Feed):
def get_object(self, request, *args, **kwargs):
- self.tag_slug = kwargs.get('tag_slug', None)
- if self.tag_slug:
- self.tag = get_object_or_404(Tag, slug=self.tag_slug)
+ self.tags = None
+ self.tag_slugs = kwargs.get('tag_slugs', None)
+ self.tag_slug_list = []
+ if self.tag_slugs:
+ self.tag_slug_list = self.tag_slugs.split('+')
+ # need to fail if any item in slug list references nonexistent tag
+ self.tags = [get_object_or_404(Tag, slug=tag_slug) for tag_slug in self.tag_slug_list]
return ''
def title(self, obj):
identifier = ""
- if self.tag_slug:
- identifier = " tagged with '%s'" % self.tag.name
+ if self.tags:
+ identifier = " tagged '%s'" % "+".join([tag.name for tag in self.tags])
return "Source: Code%s" % identifier
def link(self, obj):
- if self.tag_slug:
- return reverse('code_list_by_tag', kwargs={'tag_slug': self.tag_slug})
+ if self.tag_slugs:
+ return reverse('code_list_by_tag', kwargs={'tag_slugs': self.tag_slugs})
return reverse('code_list')
def description(self, obj):
identifier = " from Source"
- if self.tag_slug:
- identifier = " tagged with '%s'" % self.tag.name
+ if self.tag_slugs:
+ identifier = " tagged '%s'" % "+".join([tag.name for tag in self.tags])
return "Recent code index pages%s" % identifier
def item_title(self, item):
@@ -92,7 +101,7 @@ def item_description(self, item):
def items(self, obj):
queryset = Code.live_objects.order_by('-created')
- if self.tag_slug:
- queryset = queryset.filter(tags__slug=self.tag_slug)
+ for tag_slug in self.tag_slug_list:
+ queryset = queryset.filter(tags__slug=tag_slug)
return queryset[:20]
View
2  source/code/templates/code/_base_code.html
@@ -1,3 +1,3 @@
{% extends "base.html" %}
{% set active_nav = "code" %}
-{% block page_title %}Code Index - {{ super() }}{% endblock %}
+{% block page_title %}Code Index{% if tags %} entries tagged: {% for tag in tags %}{{ tag.name }}{% if not loop.last %}, {% endif %}{% endfor %}{% endif %} - {{ super() }}{% endblock %}
View
4 source/code/templates/code/code_list.html
@@ -4,9 +4,9 @@
<h1 class="maintopic"><a href="{{ url('code_list') }}">Code</a>{% if tag %} / <span class="category">{{ tag.name }}</span>{% endif %}</h1>
<div id="filterable-list">
-{% if tag %}
+{% if tags %}
<div class="grouper-block filter-block">
- <h2 class="grouper-header"><span class="category">Code index entries tagged: {{ tag.name }}</span></h2>
+ <h2 class="grouper-header"><span class="category">Code index entries tagged: {% for tag in tags %}{{ tag.name }}{% if not loop.last %}, {% endif %}{% endfor %}</span></h2>
{% for code in object_list %}
<div class="grid-box">
<h3><a href="{{ code.get_absolute_url() }}">{{ code.name }}</a></h3>
View
6 source/code/urls.py
@@ -26,19 +26,19 @@
name = 'code_list_feed_json',
),
url(
- regex = '^tags/(?P<tag_slug>[-\w]+)/$',
+ regex = '^tags/(?P<tag_slugs>[-\w\+]+)/$',
view = CodeList.as_view(),
kwargs = {},
name = 'code_list_by_tag',
),
url(
- regex = '^tags/(?P<tag_slug>[-\w]+)/rss/$',
+ regex = '^tags/(?P<tag_slugs>[-\w\+]+)/rss/$',
view = cache_page(CodeFeed(), 60*15),
kwargs = {},
name = 'code_list_by_tag_feed',
),
url(
- regex = '^tags/(?P<tag_slug>[-\w]+)/json/$',
+ regex = '^tags/(?P<tag_slugs>[-\w\+]+)/json/$',
view = cache_page(CodeList.as_view(), 60*15),
kwargs = {'render_json': True},
name = 'code_list_by_tag_feed_json',
View
23 source/code/views.py
@@ -13,17 +13,20 @@ class CodeList(ListView):
def dispatch(self, *args, **kwargs):
self.render_json = kwargs.get('render_json', False)
- self.tag_slug = kwargs.get('tag_slug', None)
- self.tag = None
-
+ self.tags = None
+ self.tag_slugs = kwargs.get('tag_slugs', None)
+ self.tag_slug_list = []
return super(CodeList, self).dispatch(*args, **kwargs)
def get_queryset(self):
queryset = Code.live_objects.prefetch_related('organizations')
- if self.tag_slug:
- self.tag = get_object_or_404(Tag, slug=self.tag_slug)
- queryset = queryset.filter(tags__slug=self.kwargs['tag_slug'])
+ if self.tag_slugs:
+ self.tag_slug_list = self.tag_slugs.split('+')
+ # need to fail if any item in slug list references nonexistent tag
+ self.tags = [get_object_or_404(Tag, slug=tag_slug) for tag_slug in self.tag_slug_list]
+ for tag_slug in self.tag_slug_list:
+ queryset = queryset.filter(tags__slug=tag_slug)
return queryset
@@ -31,10 +34,10 @@ def get_context_data(self, **kwargs):
context = super(CodeList, self).get_context_data(**kwargs)
context['active_nav'] = 'Code'
- if self.tag:
- context['tag'] = self.tag
- context['rss_link'] = reverse('code_list_by_tag_feed', kwargs={'tag_slug': self.tag_slug})
- context['json_link'] = reverse('code_list_by_tag_feed_json', kwargs={'tag_slug': self.tag_slug})
+ if self.tags:
+ context['tags'] = self.tags
+ context['rss_link'] = reverse('code_list_by_tag_feed', kwargs={'tag_slugs': self.tag_slugs})
+ context['json_link'] = reverse('code_list_by_tag_feed_json', kwargs={'tag_slugs': self.tag_slugs})
else:
context['rss_link'] = reverse('code_list_feed')
context['json_link'] = reverse('code_list_feed_json')
View
2  source/people/templates/people/organization_detail.html
@@ -10,7 +10,7 @@ <h1 class="maintopic"><a href="{{ url('organization_list') }}">Organizations</a>
{% if organization.location_string_for_static_map %}
<div class="image-inset-right-wrapper">
- <a href="https://maps.google.com/maps?q={{ organization.location_string_for_static_map }}"><img src="https://maps.googleapis.com/maps/api/staticmap?sensor=false&scale=2&zoom=13&maptype=terrain&size=300x250&markers=size:small|color:AD3121|{{ organization.location_string_for_static_map }}" class="map-inset-right"></a>
+ <a href="https://maps.google.com/maps?q={{ organization.location_string_for_static_map }}"><img src="https://maps.googleapis.com/maps/api/staticmap?sensor=false&scale=2&zoom=13&maptype=terrain&size=300x250&markers=size:small|color:AD3121|{{ organization.location_string_for_static_map }}" alt="{{ organization.name }} location" class="map-inset"></a>
{% if organization.address or organization.location_string_city %}<p class="caption">{% if organization.address %}{{ organization.address }}{% endif %}{% if organization.address and organization.location_string_city %}, {% endif %}{% if organization.location_string_city %}{{ organization.location_string_city }}{% endif %}</p>{% endif %}
</div>
{% endif %}
Something went wrong with that request. Please try again.