forked from 00dani/lemoncurry
Add basic support for tags on entries :3 cool beans
This commit is contained in:
parent
e72a6b01f0
commit
1a6ec02664
6 changed files with 99 additions and 2 deletions
26
entries/migrations/0009_tag.py
Normal file
26
entries/migrations/0009_tag.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11.7 on 2017-11-19 23:43
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('entries', '0008_auto_20171116_2116'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Tag',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=255, unique=True)),
|
||||||
|
('slug', models.CharField(max_length=255, unique=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'ordering': ('name',),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
20
entries/migrations/0010_entry_tags.py
Normal file
20
entries/migrations/0010_entry_tags.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11.7 on 2017-11-19 23:46
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('entries', '0009_tag'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='entry',
|
||||||
|
name='tags',
|
||||||
|
field=models.ManyToManyField(related_name='entries', to='entries.Tag'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -17,6 +17,25 @@ from lemoncurry import requests
|
||||||
ENTRY_KINDS = [(k.id, k.id) for k in kinds.all]
|
ENTRY_KINDS = [(k.id, k.id) for k in kinds.all]
|
||||||
|
|
||||||
|
|
||||||
|
class TagManager(models.Manager):
|
||||||
|
def from_name(self, name):
|
||||||
|
tag, created = self.get_or_create(name=name, slug=slugify(name))
|
||||||
|
return tag
|
||||||
|
|
||||||
|
|
||||||
|
class Tag(models.Model):
|
||||||
|
objects = TagManager()
|
||||||
|
name = models.CharField(max_length=255, unique=True)
|
||||||
|
slug = models.CharField(max_length=255, unique=True)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def url(self):
|
||||||
|
return reverse('entries:tagged', args=(self.slug,))
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ('name',)
|
||||||
|
|
||||||
|
|
||||||
class EntryManager(models.Manager):
|
class EntryManager(models.Manager):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
qs = super(EntryManager, self).get_queryset()
|
qs = super(EntryManager, self).get_queryset()
|
||||||
|
@ -36,6 +55,8 @@ class Entry(ModelMeta, TimeStampedModel):
|
||||||
photo = models.ImageField(blank=True)
|
photo = models.ImageField(blank=True)
|
||||||
content = models.TextField()
|
content = models.TextField()
|
||||||
|
|
||||||
|
tags = models.ManyToManyField(Tag, related_name='entries')
|
||||||
|
|
||||||
in_reply_to = models.CharField(max_length=255, blank=True)
|
in_reply_to = models.CharField(max_length=255, blank=True)
|
||||||
like_of = models.CharField(max_length=255, blank=True)
|
like_of = models.CharField(max_length=255, blank=True)
|
||||||
repost_of = models.CharField(max_length=255, blank=True)
|
repost_of = models.CharField(max_length=255, blank=True)
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
{% if entry.name %}<h4 class="card-title p-name">{{ entry.name }}</h4>{% endif %}
|
{% if entry.name %}<h4 class="card-title p-name">{{ entry.name }}</h4>{% endif %}
|
||||||
<div class="e-content{% if not entry.name %} p-name{% endif %}">{{ entry.content | markdown }}</div>
|
<div class="e-content{% if not entry.name %} p-name{% endif %}">{{ entry.content | markdown }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
<a class="p-author h-card" href="{{ entry.author.url }}">
|
<a class="p-author h-card" href="{{ entry.author.url }}">
|
||||||
<img class="u-photo" src="{{ entry.author.avatar.url }}" />
|
<img class="u-photo" src="{{ entry.author.avatar.url }}" />
|
||||||
|
@ -38,6 +39,21 @@
|
||||||
{{ entry.updated | naturaltime }}
|
{{ entry.updated | naturaltime }}
|
||||||
</time>
|
</time>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if entry.tags.exists %}
|
||||||
|
<div class="card-footer">
|
||||||
|
{% for t in entry.tags.all %}
|
||||||
|
<a class="p-category" href="{{ t.url }}">
|
||||||
|
<i class="fa fa-hashtag"></i>
|
||||||
|
{{ t.name }}
|
||||||
|
</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if entry.syndications.exists %}
|
||||||
|
<div class="card-footer">
|
||||||
{% for s in entry.syndications.all %}
|
{% for s in entry.syndications.all %}
|
||||||
<a class="u-syndication" href="{{ s.url }}">
|
<a class="u-syndication" href="{{ s.url }}">
|
||||||
<i class="{{ s.profile.site.icon }}"></i>
|
<i class="{{ s.profile.site.icon }}"></i>
|
||||||
|
@ -45,5 +61,7 @@
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<script class="p-json-ld" type="application/ld+json">{{ entry.json_ld | jsonify }}</script>
|
<script class="p-json-ld" type="application/ld+json">{{ entry.json_ld | jsonify }}</script>
|
||||||
</article>
|
</article>
|
||||||
|
|
|
@ -15,7 +15,10 @@ app_name = 'entries'
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url('^atom$', feeds.AtomHomeEntries(), name='atom'),
|
url('^atom$', feeds.AtomHomeEntries(), name='atom'),
|
||||||
url('^rss$', feeds.RssHomeEntries(), name='rss'),
|
url('^rss$', feeds.RssHomeEntries(), name='rss'),
|
||||||
|
url('^tags/(?P<slug>.+)$', views.tagged, name='tagged'),
|
||||||
]
|
]
|
||||||
|
crumbs.add(prefix('tagged'), parent='home:index')
|
||||||
|
|
||||||
for k in kinds.all:
|
for k in kinds.all:
|
||||||
kind = k.plural
|
kind = k.plural
|
||||||
id = r'/(?P<id>\d+)'
|
id = r'/(?P<id>\d+)'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from annoying.decorators import render_to
|
from annoying.decorators import render_to
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import get_object_or_404, redirect
|
||||||
from .models import Entry
|
from .models import Entry, Tag
|
||||||
|
|
||||||
|
|
||||||
@render_to('entries/index.html')
|
@render_to('entries/index.html')
|
||||||
|
@ -14,6 +14,15 @@ def index(request, kind):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@render_to('entries/index.html')
|
||||||
|
def tagged(request, slug):
|
||||||
|
tag = get_object_or_404(Tag, slug=slug)
|
||||||
|
return {
|
||||||
|
'entries': tag.entries.all(),
|
||||||
|
'title': '#' + tag.name,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@render_to('entries/entry.html')
|
@render_to('entries/entry.html')
|
||||||
def entry(request, id, slug=None):
|
def entry(request, id, slug=None):
|
||||||
entry = Entry.objects.get(pk=id)
|
entry = Entry.objects.get(pk=id)
|
||||||
|
|
Loading…
Reference in a new issue