Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assorted SEO improvements #757

Merged
merged 18 commits into from
Jun 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion association/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
from organization.models import Organization
from location.models import Location
from sfm_pc.models import GetComplexFieldNameMixin
from source.mixins import SourcesMixin


class Association(models.Model, BaseModel, GetComplexFieldNameMixin):
class Association(models.Model, BaseModel, SourcesMixin, GetComplexFieldNameMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.startdate = ComplexFieldContainer(self, AssociationStartDate)
Expand Down
3 changes: 2 additions & 1 deletion composition/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
from complex_fields.models import ComplexField, ComplexFieldContainer
from complex_fields.base_models import BaseModel
from sfm_pc.models import GetComplexFieldNameMixin
from source.mixins import SourcesMixin


class Composition(models.Model, BaseModel, GetComplexFieldNameMixin):
class Composition(models.Model, BaseModel, SourcesMixin, GetComplexFieldNameMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.parent = ComplexFieldContainer(self, CompositionParent)
Expand Down
Binary file modified configs/sfm.conf.production.nginx.gpg
Binary file not shown.
3 changes: 2 additions & 1 deletion emplacement/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
from organization.models import Organization
from location.models import Location
from sfm_pc.models import GetComplexFieldNameMixin
from source.mixins import SourcesMixin


class Emplacement(models.Model, BaseModel, GetComplexFieldNameMixin):
class Emplacement(models.Model, BaseModel, SourcesMixin, GetComplexFieldNameMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.startdate = ComplexFieldContainer(self, EmplacementStartDate)
Expand Down
3 changes: 2 additions & 1 deletion membershiporganization/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
from complex_fields.base_models import BaseModel
from organization.models import Organization
from sfm_pc.models import GetComplexFieldNameMixin
from source.mixins import SourcesMixin


class MembershipOrganization(models.Model, BaseModel, GetComplexFieldNameMixin):
class MembershipOrganization(models.Model, BaseModel, SourcesMixin, GetComplexFieldNameMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.member = ComplexFieldContainer(self, MembershipOrganizationMember)
Expand Down
3 changes: 2 additions & 1 deletion membershipperson/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
from person.models import Person
from organization.models import Organization
from sfm_pc.models import GetComplexFieldNameMixin
from source.mixins import SourcesMixin


class MembershipPerson(models.Model, BaseModel, GetComplexFieldNameMixin):
class MembershipPerson(models.Model, BaseModel, SourcesMixin, GetComplexFieldNameMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.member = ComplexFieldContainer(self, MembershipPersonMember)
Expand Down
4 changes: 3 additions & 1 deletion organization/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

from sfm_pc.utils import VersionsMixin
from sfm_pc.models import GetComplexFieldNameMixin
from source.mixins import SourcesMixin


VERSION_RELATED_FIELDS = [
'associationorganization_set',
Expand All @@ -38,7 +40,7 @@


@reversion.register(follow=VERSION_RELATED_FIELDS)
class Organization(models.Model, BaseModel, VersionsMixin, GetComplexFieldNameMixin):
class Organization(models.Model, BaseModel, SourcesMixin, VersionsMixin, GetComplexFieldNameMixin):

uuid = models.UUIDField(default=uuid.uuid4,
editable=False,
Expand Down
3 changes: 2 additions & 1 deletion organization/urls.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from django.conf.urls import url
from django.views.decorators.cache import cache_page

from organization import views

urlpatterns = [
url(r'^view/(?P<slug>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/$',
views.OrganizationDetail.as_view(),
cache_page(60 * 60 * 24)(views.OrganizationDetail.as_view()),
name="view-organization"),
url(r'name/autocomplete',
views.organization_autocomplete,
Expand Down
37 changes: 37 additions & 0 deletions organization/views.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from datetime import date
from itertools import chain
import json

from django.http import HttpResponse, HttpResponseRedirect
from django.core.urlresolvers import reverse, reverse_lazy
from django.db.models import Q
from django.core.serializers import serialize
from django.contrib.sitemaps import Sitemap

from emplacement.models import Emplacement

Expand Down Expand Up @@ -43,6 +46,29 @@ class OrganizationDetail(BaseDetailView):
template_name = 'organization/view.html'
slug_field = 'uuid'

def get_sources(self, context):
sources = list(context['organization'].sources)

original_list = sources.copy()

related_entities = (
'person_members',
'org_members',
'memberships',
'subsidiaries',
'events',
'emplacements',
'associations',
'parents',
)

for relation in related_entities:
sources += list(
chain.from_iterable(entity.sources for entity in context[relation])
)

return sorted(set(sources), key=lambda x: x.get_published_date() or date.min, reverse=True)

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)

Expand Down Expand Up @@ -190,6 +216,8 @@ def get_context_data(self, **kwargs):

context['parents_list'].append(org_data)

context['sources'] = self.get_sources(context)

return context


Expand Down Expand Up @@ -678,3 +706,12 @@ def organization_autocomplete(request):
response['results'].append(result)

return HttpResponse(json.dumps(response), content_type='application/json')


class OrganizationSitemap(Sitemap):

def items(self):
return Organization.objects.filter(published=True).order_by('id')

def location(self, obj):
return reverse('view-organization', args=[obj.uuid])
3 changes: 2 additions & 1 deletion person/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from sfm_pc.utils import VersionsMixin
from sfm_pc.models import GetComplexFieldNameMixin
from source.mixins import SourcesMixin


VERSION_RELATED_FIELDS = [
Expand All @@ -31,7 +32,7 @@


@reversion.register(follow=VERSION_RELATED_FIELDS)
class Person(models.Model, BaseModel, VersionsMixin, GetComplexFieldNameMixin):
class Person(models.Model, BaseModel, SourcesMixin, VersionsMixin, GetComplexFieldNameMixin):

uuid = models.UUIDField(default=uuid.uuid4,
editable=False,
Expand Down
2 changes: 1 addition & 1 deletion person/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
views.PersonDeletePostingView.as_view(),
name='delete-person-posting'),
url(r'^view/(?P<slug>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/$',
views.PersonDetail.as_view(),
cache_page(60 * 60 * 24)(views.PersonDetail.as_view()),
name="view-person"),
url(r'autocomplete/$',
views.person_autocomplete,
Expand Down
35 changes: 32 additions & 3 deletions person/views.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import json

from datetime import date
from collections import namedtuple
from itertools import chain

from django.http import HttpResponse, HttpResponseRedirect
from django.db import connection
from django.contrib.sitemaps import Sitemap
from django.core.urlresolvers import reverse, reverse_lazy
from django.db import connection
from django.http import HttpResponse, HttpResponseRedirect
from django.utils.translation import ugettext as _

from person.models import Person
Expand All @@ -21,6 +22,23 @@ class PersonDetail(BaseDetailView):
template_name = 'person/view.html'
slug_field = 'uuid'

def get_sources(self, context):
sources = list(context['person'].sources)

sources += list(
chain.from_iterable(m.sources for m in context['memberships'])
)

sources += list(
chain.from_iterable(sub['commander'].sources for sub in context['subordinates'])
)

sources += list(
chain.from_iterable(sub['commander'].sources for sub in context['superiors'])
)

return sorted(set(sources), key=lambda x: x.get_published_date() or date.min, reverse=True)

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)

Expand Down Expand Up @@ -125,6 +143,8 @@ def get_context_data(self, **kwargs):
for event in events:
context['events'].append(event.object_ref)

context['sources'] = list(self.get_sources(context))

return context


Expand Down Expand Up @@ -474,3 +494,12 @@ def delete(self, request, *args, **kwargs):
organization.object_ref_saved()

return response


class PersonSitemap(Sitemap):

def items(self):
return Person.objects.filter(published=True).order_by('id')

def location(self, obj):
return reverse('view-person', args=[obj.uuid])
6 changes: 4 additions & 2 deletions sfm_pc/base_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

from extra_views import FormSetView

from source.models import AccessPoint
from source.models import AccessPoint, Source
from association.models import Association
from emplacement.models import Emplacement
from person.models import Person
Expand Down Expand Up @@ -67,7 +67,9 @@ def get_context_data(self, *args, **kwargs):
'Person': Person,
'MembershipPerson': MembershipPerson,
'Violation': Violation,
'Organization': Organization
'Organization': Organization,
'Source': Source,
'AccessPoint': AccessPoint,
}
return context

Expand Down
7 changes: 6 additions & 1 deletion sfm_pc/management/commands/import_google_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from tqdm import tqdm

from django.core.cache import cache
from django.core.exceptions import ValidationError
from django.core.management.base import BaseCommand
from django.db import models, IntegrityError
Expand Down Expand Up @@ -228,7 +229,11 @@ def handle(self, *args, **options):

data_src = options['folder'] if options.get('folder') else options['doc_id']
self.stdout.write(self.style.SUCCESS('Successfully imported data from {}'.format(data_src)))
# connect post save signals

# Clear cached detail and command chart views
cache.clear()

# Connect post save signals
self.connectSignals()

def create_locations(self):
Expand Down
1 change: 1 addition & 0 deletions sfm_pc/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
'django.contrib.staticfiles',
'django.contrib.gis',
'django.contrib.humanize',
'django.contrib.sitemaps',
'haystack',
'django_date_extensions',
'rosetta',
Expand Down
10 changes: 8 additions & 2 deletions sfm_pc/templatetags/citations.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,24 @@ def get_citation_string(obj):

for i, attr in enumerate(info):
key, val = attr[0], attr[1]
event = ''

# Wrap links in anchors
if key == _('Source URL') or key == _('Archive URL'):
html_fmt = '<strong>{0}</strong>: <a href="{1}" target="_blank">{1}</a>'
html_fmt = (
'<strong>{0}</strong>: <a href="{1}" target="_blank" '
'onclick="_paq.push([\'trackEvent\', \'Citation '
'Interaction\', \'{2} Click\', \'{1}\']);">{1}</a>'
)
event = 'Source Link' if key == _('Source URL') else 'Archive Link'
else:
html_fmt = '<strong>{0}</strong>: {1}'

html_str = ''
if i != 0:
html_str = '<br/>'

html_str += html_fmt.format(key, val)
html_str += html_fmt.format(key, val, event)
html += html_str

source_citation += html
Expand Down
8 changes: 4 additions & 4 deletions sfm_pc/templatetags/countries.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def country_name(division_id):
# so that we don't mess with the template
return ''

@register.inclusion_tag('partials/location_string.html')
@register.simple_tag
def render_location_string(obj, countries=True):

context = {}
Expand All @@ -48,9 +48,9 @@ def render_location_string(obj, countries=True):
obj.adminlevel1.get_value(),
obj.adminlevel2.get_value()]

context['locations'] = [loc for loc in locations if loc is not None]
locations = [loc for loc in locations if loc is not None]

if countries and country_name(obj.division_id.get_value()) is not None:
context['locations'].append(country_name(obj.division_id.get_value()))
locations.append(country_name(obj.division_id.get_value()))

return context
return ', '.join(str(loc) for loc in locations)
34 changes: 31 additions & 3 deletions sfm_pc/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,43 @@
from django.conf.urls.static import static
from django.contrib import admin
from django.contrib.auth.views import logout_then_login
from django.contrib.sitemaps import views as sitemap_views, Sitemap
from django.views.decorators.cache import cache_page
from django.core.urlresolvers import reverse_lazy
from django.core.urlresolvers import reverse, reverse_lazy

from organization.views import OrganizationSitemap
from person.views import PersonSitemap
from violation.views import ViolationSitemap

from sfm_pc.views import (Dashboard, osm_autocomplete, division_autocomplete,
command_chain, DownloadData, DumpChangeLog,
download_zip, About, about_redirect)

urlpatterns = i18n_patterns(

class StaticViewSitemap(Sitemap):
i18n = True

def items(self):
return ['dashboard', 'about', 'download']

def location(self, item):
return reverse(item)

sitemaps = {
'organization': OrganizationSitemap,
'person': PersonSitemap,
'violation': ViolationSitemap,
'static': StaticViewSitemap,
}

urlpatterns = [
# sitemap
url(r'^sitemap\.xml$', sitemap_views.index, {'sitemaps': sitemaps}),
url(r'^sitemap-(?P<section>.+)\.xml$', sitemap_views.sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap'),
]

urlpatterns += i18n_patterns(
url(r'^organization/', include('organization.urls')),
url(r'^person/', include('person.urls')),
url(r'^source/', include('source.urls')),
Expand Down Expand Up @@ -47,7 +76,6 @@

# auth
url('^', include('django.contrib.auth.urls')),

)

# Rosetta translation app
Expand Down
Loading