Add Internationalization & localization

This commit is contained in:
Nyymix 2025-05-03 21:47:56 +03:00
parent e37c412fd9
commit f68db77e82
18 changed files with 488 additions and 257 deletions

View file

@ -1,5 +1,7 @@
from pathlib import Path
from django.utils.translation import gettext_lazy as _
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
@ -13,6 +15,24 @@ ALLOWED_HOSTS = []
INTERNAL_IPS = ['localhost', '127.0.0.1',]
#
LANGUAGES = [
('en', _('English')),
('fi', _('Finnish')),
]
LANGUAGE_CODE = 'en'
USE_I18N = True
USE_L10N = True
USE_TZ = True
LOCALE_PATHS = [
BASE_DIR / 'locale',
]
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
@ -30,6 +50,7 @@ INSTALLED_APPS = [
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware', # Locale
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',

View file

@ -1,4 +1,5 @@
from django.conf import settings
from django.conf.urls.i18n import i18n_patterns
from django.conf.urls.static import static
from django.contrib import admin
from django.contrib.sitemaps.views import sitemap
@ -15,14 +16,10 @@ urlpatterns = [
path("sitemap.xml", sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'),
path('admin/', admin.site.urls),
path('favicon.ico/', RedirectView.as_view(url='/static/favicon.ico', permanent=True)),
path('i18n/', include('django.conf.urls.i18n')),
path('', include(('gallery.urls', 'gallery'), namespace='gallery')),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View file

@ -1,9 +1,10 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load gallery_stats %}
<!-- Title -->
{% block title %} About {% endblock %}
{% block title %} {% trans "About" %} {% endblock %}
<!-- Parallax -->
{% block parallax %}
@ -16,8 +17,8 @@
<!-- Breadcrumb -->
<div class="uk-margin uk-background-secondary uk-padding-small uk-light">
<ul class="uk-breadcrumb uk-margin-remove uk-flex uk-flex-middle">
<li><a href="{% url 'gallery:main_url' %}">Home</a></li>
<li class="uk-disabled"><a>About</a></li>
<li><a href="{% url 'gallery:main_url' %}">{% trans "Home" %}</a></li>
<li class="uk-disabled"><a>{% trans "About" %}</a></li>
</ul>
</div>
@ -27,22 +28,30 @@
<div class="uk-width-1-1">
<div class="uk-card uk-card-default uk-card-body uk-text-center">
<h3 class="uk-card-title">Muistox gallery</h3>
<h3 class="uk-card-title">{% trans "Muistox gallery" %}</h3>
<img class="uk-border-circle uk-box-shadow-small uk-margin-small"
src="{% static "img/default.png" %}"
alt="Profile photo" width="120">
<p class="uk-text-muted uk-margin-small">
Just another wannabe photographer...
{% trans "Just another wannabe photographer..." %}
</p>
<hr class="uk-divider-icon">
<div class="uk-text-small uk-text-muted">
<p>
<strong>{{ counts.0 }}</strong> <a href="{% url 'gallery:albums_url' %}">Albums</a> (public {{ counts.1 }}),
<strong>{{ counts.2 }}</strong> <a href="{% url 'gallery:photos_url' %}">Photos</a></p>
<strong>{{ counts.0 }}</strong>&nbsp;
<a href="{% url 'gallery:albums_url' %}">
{% blocktrans count album_count=counts.0 %}album{% plural %}albums{% endblocktrans %}
</a>
(&nbsp;{% blocktrans count public_count=counts.1 %}{{ public_count }} public{% plural %}{{ public_count }} public{% endblocktrans %}&nbsp;)
<strong>{{ counts.2 }}</strong>&nbsp;
<a href="{% url 'gallery:photos_url' %}">
{% blocktrans count photo_count=counts.2 %}photo{% plural %}photos{% endblocktrans %}
</a>
</p>
</div>
</div>

View file

@ -1,6 +1,6 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
<!-- Title -->
{% block title %} {{ album.name }} {% endblock %}
@ -32,32 +32,15 @@
<!-- Breadcrumb -->
<div class="uk-margin uk-background-secondary uk-padding-small uk-light">
<ul class="uk-breadcrumb uk-margin-remove uk-flex uk-flex-middle">
<li><a href="{% url 'gallery:main_url' %}">Home</a></li>
<li><a href="{% url 'gallery:albums_url' %}">Albums</a></li>
<li><a href="{% url 'gallery:main_url' %}">{% trans "Home" %}</a></li>
<li><a href="{% url 'gallery:albums_url' %}">{% trans "Albums" %}</a></li>
<li class="uk-disabled"><a>{{ album.name }}</a></li>
</ul>
</div>
<div class="uk-grid-small uk-child-width-1-2 uk-child-width-1-3@s uk-child-width-1-4@m uk-child-width-1-5@l" uk-grid="masonry: true">
{% for photo in photos %}
<a href="{{ photo.get_absolute_url }}">
<img
loading="lazy"
src="{{ photo.photo_sm.url }}"
srcset="
{{ photo.photo_sm.url }} 320w,
{{ photo.photo_md.url }} 720w,
{{ photo.photo_bg.url }} 1920w
"
sizes="(max-width: 640px) 50vw,
(max-width: 960px) 33vw,
(max-width: 1200px) 25vw,
20vw"
width="{{ photo.width }}"
height="{{ photo.height }}"
style="aspect-ratio: {{ photo.aspect_ratio }};"
alt="{{ photo.album.name }} - {{ photo.slug }}">
</a>
{% include "gallery/partials/photo_thumbnail.html" with photo=photo %}
{% endfor %}
</div>

View file

@ -1,9 +1,9 @@
{% extends "base.html" %}
{% load static %}
{% load image_tags %}
{% load i18n %}
<!-- Title -->
{% block title %} Albums {% endblock %}
{% block title %} {% trans "Albums" %} {% endblock %}
<!-- Parallax -->
{% block parallax %}
@ -16,50 +16,15 @@
<!-- Breadcrumb -->
<div class="uk-margin uk-background-secondary uk-padding-small uk-light">
<ul class="uk-breadcrumb uk-margin-remove uk-flex uk-flex-middle">
<li><a href="{% url 'gallery:main_url' %}">Home</a></li>
<li class="uk-disabled"><a>Albums</a></li>
<li><a href="{% url 'gallery:main_url' %}">{% trans "Home" %}</a></li>
<li class="uk-disabled"><a>{% trans "Albums" %}</a></li>
</ul>
</div>
<div class="uk-grid-small uk-child-width-1-2@s uk-child-width-1-3@m" uk-grid="masonry: true">
{% for album in album_list %}
<div>
<div class="uk-card uk-card-default uk-height-1-1">
<!-- Album cover image -->
<div class="uk-card-media-top">
<a href="{{ album.get_absolute_url }}">
{% with album.cover|photo_image_data as img %}
<div class="{% if img.is_placeholder %}uk-blur{% endif %}">
<img
src="{{ img.url }}"
width="{{ img.width }}"
height="{{ img.height }}"
style="aspect-ratio: {{ img.aspect_ratio }};"
alt="Cover image for {{ album.name }}"
title="{{ album.name }}"
loading="lazy"
decoding="async"
onload="this.parentElement.classList.remove('uk-blur'); this.classList.add('fade-in');">
</div>
{% endwith %}
</a>
</div>
<!-- Album info overlay -->
<div class="uk-overlay uk-overlay-primary uk-position-bottom uk-padding-small">
<h3 class="uk-card-title uk-margin-remove-bottom">
<a href="{{ album.get_absolute_url }}">{{ album }}</a>
</h3>
<p class="uk-text-small uk-margin-remove-top">
{{ album.photos_in_album }} photos &bull;
{{ album.photos_views }} views
</p>
</div>
</div>
</div>
{% include "gallery/partials/album_card.html" %}
{% endfor %}
</div>

View file

@ -1,9 +1,10 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load image_tags %}
<!-- Title -->
{% block title %} Search {% endblock %}
{% block title %} {% trans "Search" %} {% endblock %}
<!-- Parallax -->
{% block parallax %}
@ -16,8 +17,8 @@
<!-- Breadcrumb -->
<div class="uk-margin uk-background-secondary uk-padding-small uk-light">
<ul class="uk-breadcrumb uk-margin-remove uk-flex uk-flex-middle">
<li><a href="{% url 'gallery:main_url' %}">Home</a></li>
<li class="uk-disabled"><a>Search</a></li>
<li><a href="{% url 'gallery:main_url' %}">{% trans "Home" %}</a></li>
<li class="uk-disabled"><a>{% trans "Search" %}</a></li>
</ul>
</div>
@ -25,42 +26,7 @@
{% if results %}
{% for album in results %}
<div>
<div class="uk-card uk-card-default uk-height-1-1">
<!-- Album cover image -->
<div class="uk-card-media-top">
<a href="{{ album.get_absolute_url }}">
{% with album.cover|photo_image_data as img %}
<div class="{% if img.is_placeholder %}uk-blur{% endif %}">
<img
src="{{ img.url }}"
width="{{ img.width }}"
height="{{ img.height }}"
style="aspect-ratio: {{ img.aspect_ratio }};"
alt="Cover image for {{ album.name }}"
title="{{ album.name }}"
loading="lazy"
decoding="async"
onload="this.parentElement.classList.remove('uk-blur'); this.classList.add('fade-in');">
</div>
{% endwith %}
</a>
</div>
<!-- Album info overlay -->
<div class="uk-overlay uk-overlay-primary uk-position-bottom uk-padding-small">
<h3 class="uk-card-title uk-margin-remove-bottom">
<a href="{{ album.get_absolute_url }}">{{ album }}</a>
</h3>
<p class="uk-text-small uk-margin-remove-top">
{{ album.photos_in_album }} photos &bull;
{{ album.photos_views }} views
</p>
</div>
</div>
</div>
{% include "gallery/partials/album_card.html" %}
{% endfor %}
{% else %}
<p>Not found: "{{ query }}".</p>

View file

@ -1,9 +1,9 @@
{% extends "base.html" %}
{% load static %}
{% load image_tags %}
{% load i18n %}
<!-- Title -->
{% block title %}Home{% endblock %}
{% block title %} {% trans "Home" %} {% endblock %}
<!-- Parallax -->
{% block parallax %}
@ -13,100 +13,27 @@
<!-- Content -->
{% block content %}
<!-- Favorite random portrait photos -->
{% load top_tags %}
{% load image_tags %}
<!-- Favorite random portrait photos -->
{% random_favorite_photos_portrait 10 as top_portrait_photos %}
{% if top_portrait_photos %}
<div uk-slider>
<div class="uk-position-relative uk-visible-toggle uk-light" tabindex="-1">
<div class="uk-slider-items uk-child-width-1-2 uk-child-width-1-3@s uk-child-width-1-4@m">
{% for photo in top_portrait_photos %}
{% with photo|photo_image_data as data %}
<div>
<a href="{{ photo.get_absolute_url }}">
<img src="{{ data.url }}" alt="{{ photo.album.slug }}" width="{{ data.width }}" height="{{ data.height }}" style="object-fit: cover;" loading="lazy">
</a>
</div>
{% endwith %}
{% endfor %}
</div>
<a class="uk-position-center-left uk-position-small uk-hidden-hover" href uk-slidenav-previous uk-slider-item="previous"></a>
<a class="uk-position-center-right uk-position-small uk-hidden-hover" href uk-slidenav-next uk-slider-item="next"></a>
</div>
<ul class="uk-slider-nav uk-dotnav uk-flex-center uk-margin"></ul>
</div>
{% include "gallery/partials/photos_slider.html" with photos=top_portrait_photos %}
{% endif %}
<!-- Latest albums -->
<div class="uk-grid-small uk-child-width-1-2@s uk-child-width-1-3@m" uk-grid="masonry: true">
<div class="uk-grid-small uk-child-width-1-2@s uk-child-width-1-3@m uk-margin-bottom" uk-grid="masonry: true">
{% for album in latest_albums %}
<div>
<div class="uk-card uk-card-default uk-height-1-1">
<!-- Album cover image -->
<div class="uk-card-media-top">
<a href="{{ album.get_absolute_url }}">
{% with album.cover|photo_image_data as img %}
<div class="{% if img.is_placeholder %}uk-blur{% endif %}">
<img
src="{{ img.url }}"
width="{{ img.width }}"
height="{{ img.height }}"
style="aspect-ratio: {{ img.aspect_ratio }};"
alt="Cover image for {{ album.name }}"
title="{{ album.name }}"
loading="lazy"
decoding="async"
onload="this.parentElement.classList.remove('uk-blur'); this.classList.add('fade-in');">
</div>
{% endwith %}
</a>
</div>
<!-- Album info overlay -->
<div class="uk-overlay uk-overlay-primary uk-position-bottom uk-padding-small">
<h3 class="uk-card-title uk-margin-remove-bottom">
<a href="{{ album.get_absolute_url }}">{{ album }}</a>
</h3>
<p class="uk-text-small uk-margin-remove-top">
{{ album.photos_in_album }} photos &bull;
{{ album.photos_views }} views
</p>
</div>
</div>
</div>
{% include "gallery/partials/album_card.html" %}
{% endfor %}
</div>
<!-- Favorite random landscape photos -->
{% load top_tags %}
{% load image_tags %}
{% random_favorite_photos_landscape 10 as top_landscape_photos %}
{% if top_landscape_photos %}
<div uk-slider>
<div class="uk-position-relative uk-visible-toggle uk-light uk-margin-top" tabindex="-1">
<div class="uk-slider-items uk-child-width-1-2 uk-child-width-1-3@s uk-child-width-1-4@m">
{% for photo in top_landscape_photos %}
{% with photo|photo_image_data as data %}
<div>
<a href="{{ photo.get_absolute_url }}">
<img src="{{ data.url }}" alt="{{ photo.album.slug }}" width="{{ data.width }}" height="{{ data.height }}" style="object-fit: cover;" loading="lazy">
</a>
</div>
{% endwith %}
{% endfor %}
</div>
<a class="uk-position-center-left uk-position-small uk-hidden-hover" href uk-slidenav-previous uk-slider-item="previous"></a>
<a class="uk-position-center-right uk-position-small uk-hidden-hover" href uk-slidenav-next uk-slider-item="next"></a>
</div>
<ul class="uk-slider-nav uk-dotnav uk-flex-center uk-margin"></ul>
</div>
{% include "gallery/partials/photos_slider.html" with photos=top_landscape_photos %}
{% endif %}
{% endblock %}

View file

@ -0,0 +1,39 @@
{% load image_tags %}
{% load i18n %}
<div>
<div class="uk-card uk-card-default uk-height-1-1">
<!-- Album cover image -->
<div class="uk-card-media-top">
<a href="{{ album.get_absolute_url }}">
{% with album.cover|photo_image_data as img %}
<div class="{% if img.is_placeholder %}uk-blur{% endif %}">
<img
src="{{ img.url }}"
width="{{ img.width }}"
height="{{ img.height }}"
style="aspect-ratio: {{ img.aspect_ratio }};"
alt="Cover image for {{ album.name }}"
title="{{ album.name }}"
loading="lazy"
decoding="async"
onload="this.parentElement.classList.remove('uk-blur'); this.classList.add('fade-in');">
</div>
{% endwith %}
</a>
</div>
<!-- Album info overlay -->
<div class="uk-overlay uk-overlay-primary uk-position-bottom uk-padding-small">
<h3 class="uk-card-title uk-margin-remove-bottom">
<a href="{{ album.get_absolute_url }}">{{ album }}</a>
</h3>
<p class="uk-text-small uk-margin-remove-top">
{% blocktrans count photo_count=album.photos_in_album %}{{ photo_count }} photo{% plural %}{{ photo_count }} photos{% endblocktrans %}
&bull;
{% blocktrans count view_count=album.photos_views %}{{ view_count }} view{% plural %}{{ view_count }} views{% endblocktrans %}
</p>
</div>
</div>
</div>

View file

@ -1,3 +1,4 @@
{% load i18n %}
{% load link_tags %}
{% if page_obj.has_other_pages %}
@ -6,9 +7,9 @@
<ul class="uk-pagination uk-padding-small uk-flex-center">
{% if page_obj.has_previous %}
<li><a href="{% paginator_link page_obj.previous_page_number request.GET %}">&laquo; Prev</a></li>
<li><a href="{% paginator_link page_obj.previous_page_number request.GET %}">&laquo; {% trans "Prev" %}</a></li>
{% else %}
<li class="uk-disabled"><a href="#">&laquo; Prev</a></li>
<li class="uk-disabled"><a href="#">&laquo; {% trans "Prev" %}</a></li>
{% endif %}
{% if page_obj.number|add:'-3' > 1 %}
@ -34,9 +35,9 @@
{% endif %}
{% if page_obj.has_next %}
<li><a href="{% paginator_link page_obj.next_page_number request.GET %}">Next &raquo;</a></li>
<li><a href="{% paginator_link page_obj.next_page_number request.GET %}">{% trans "Next" %} &raquo;</a></li>
{% else %}
<li class="uk-disabled"><a href="#">Next &raquo;</a></li>
<li class="uk-disabled"><a href="#">{% trans "Next" %} &raquo;</a></li>
{% endif %}
</ul>

View file

@ -1,5 +1,6 @@
{% load top_tags %}
{% load static %}
{% load i18n %}
<div class="uk-position-relative uk-visible-toggle uk-light" tabindex="-1" uk-slideshow="ratio: 7:3; autoplay: true; animation: fade; min-height: 300;">
@ -36,9 +37,9 @@
<a class="uk-position-center-left uk-position-small uk-hidden-hover" href="#" uk-slidenav-previous uk-slideshow-item="previous"></a>
<a class="uk-position-center-right uk-position-small uk-hidden-hover" href="#" uk-slidenav-next uk-slideshow-item="next"></a>
<div class="uk-position-top uk-padding-small">
<h1>Gallery</h1>
<h1>{% trans "Gallery" %}</h1>
</div>
<div class="uk-overlay uk-overlay-primary uk-position-bottom uk-padding-small">
<p class="uk-text-small uk-margin-remove-top">Just another wannabe photographer...</p>
<p class="uk-text-small uk-margin-remove-top">{% trans "Just another wannabe photographer..." %}</p>
</div>
</div>

View file

@ -0,0 +1,18 @@
<a href="{{ photo.get_absolute_url }}">
<img
loading="lazy"
src="{{ photo.photo_sm.url }}"
srcset="
{{ photo.photo_sm.url }} 320w,
{{ photo.photo_md.url }} 720w,
{{ photo.photo_bg.url }} 1920w
"
sizes="(max-width: 640px) 50vw,
(max-width: 960px) 33vw,
(max-width: 1200px) 25vw,
20vw"
width="{{ photo.width }}"
height="{{ photo.height }}"
style="aspect-ratio: {{ photo.aspect_ratio }};"
alt="{{ photo.album.name }} - {{ photo.slug }}">
</a>

View file

@ -0,0 +1,20 @@
{% load image_tags %}
<div uk-slider>
<div class="uk-position-relative uk-visible-toggle uk-light" tabindex="-1">
<div class="uk-slider-items uk-child-width-1-2 uk-child-width-1-3@s uk-child-width-1-4@m">
{% for photo in photos %}
{% with photo|photo_image_data as data %}
<div>
<a href="{{ photo.get_absolute_url }}">
<img src="{{ data.url }}" alt="{{ photo.album.slug }}" width="{{ data.width }}" height="{{ data.height }}" style="object-fit: cover;" loading="lazy">
</a>
</div>
{% endwith %}
{% endfor %}
</div>
<a class="uk-position-center-left uk-position-small uk-hidden-hover" href uk-slidenav-previous uk-slider-item="previous"></a>
<a class="uk-position-center-right uk-position-small uk-hidden-hover" href uk-slidenav-next uk-slider-item="next"></a>
</div>
<ul class="uk-slider-nav uk-dotnav uk-flex-center uk-margin"></ul>
</div>

View file

@ -1,4 +1,5 @@
{% extends "base.html" %}
{% load i18n %}
{% load exif_filters %}
<!-- Title -->
@ -47,8 +48,8 @@
<div class="uk-margin uk-background-secondary uk-padding-small uk-light">
<div class="uk-flex uk-flex-between uk-flex-wrap uk-flex-middle">
<ul class="uk-breadcrumb uk-margin-remove uk-flex uk-flex-middle">
<li><a href="{% url 'gallery:main_url' %}">Home</a></li>
<li><a href="{% url 'gallery:albums_url' %}">Albums</a></li>
<li><a href="{% url 'gallery:main_url' %}">{% trans "Home" %}</a></li>
<li><a href="{% url 'gallery:albums_url' %}">{% trans "Albums" %}</a></li>
<li><a href="{{ photo.album.get_absolute_url }}">{{ photo.album.name }}</a></li>
<li class="uk-disabled"><a>{{ photo.slug }}</a></li>
</ul>
@ -60,38 +61,38 @@
<div>
<div class="uk-card uk-card-default uk-card-body">
<h3 class="uk-card-title">Photo Info</h3>
<h3 class="uk-card-title">{% trans "Photo Info" %}</h3>
<div class="uk-grid-small" uk-grid>
<div class="uk-width-expand" uk-leader>Album name</div>
<div class="uk-width-expand" uk-leader>{% trans "Album" %}</div>
<div><a href="{{ photo.album.get_absolute_url }}">{{ photo.album.name }}</a></div>
</div>
<div class="uk-grid-small" uk-grid>
<div class="uk-width-expand" uk-leader>Photo id</div>
<div class="uk-width-expand" uk-leader>{% trans "Photo Name" %}</div>
<div uk-lightbox>
<a href="{{ photo.photo_bg.url }}">{{ photo.slug }}</a>
</div>
</div>
<div class="uk-grid-small" uk-grid>
<div class="uk-width-expand" uk-leader>Photo Taken</div>
<div class="uk-width-expand" uk-leader>{% trans "Photo Taken" %}</div>
<div>{{ photo.taken_at|date:"d.m.Y H:i" }}</div>
</div>
<div class="uk-grid-small" uk-grid>
<div class="uk-width-expand" uk-leader>Views</div>
<div class="uk-width-expand" uk-leader>{% trans "Views" %}</div>
<div>{{ photo.views }}</div>
</div>
<div class="uk-grid-small" uk-grid>
<div class="uk-width-expand" uk-leader>Likes</div>
<div class="uk-width-expand" uk-leader>{% trans "Likes" %}</div>
<div id="like-count">{{ photo.likes }}</div>
</div>
<div class="uk-flex uk-flex-between uk-flex-middle uk-grid-small" uk-grid>
<a href="{% url 'gallery:photo_slideshow_url' photo.album.slug photo.slug %}" class="uk-button uk-button-secondary">
<span uk-icon="icon: play"></span> <span>Slideshow</span>
<span uk-icon="icon: play"></span> <span>{% trans "Slideshow" %}</span>
</a>
<a href="{{ photo.photo.url }}" class="uk-button uk-button-secondary" class="uk-button uk-button-secondary" download>
<span uk-icon="icon: download"></span> <span>Download {{ photo.width }}×{{ photo.height }}</span>
<span uk-icon="icon: download"></span> <span>{% trans "Download" %} {{ photo.width }}×{{ photo.height }}</span>
</a>
<button id="like-button" class="uk-button uk-button-secondary">
<span uk-icon="icon: heart" id="heart-icon"></span> <span id="like-text">Like</span>
<span uk-icon="icon: heart" id="heart-icon"></span> <span id="like-text">{% trans "Like" %}</span>
</button>
</div>
</div>
@ -100,37 +101,37 @@
<div>
<div class="uk-card uk-card-default uk-card-body">
<h3 class="uk-card-title">Exif</h3>
<h3 class="uk-card-title">{% trans "Exif" %}</h3>
<div class="uk-grid-small" uk-grid>
<div class="uk-width-expand" uk-leader>Camera</div>
<div class="uk-width-expand" uk-leader>{% trans "Camera" %}</div>
<div>{{ photo.exif.Model }}</div>
</div>
<div class="uk-grid-small" uk-grid>
<div class="uk-width-expand" uk-leader>Lens</div>
<div class="uk-width-expand" uk-leader>{% trans "Lens" %}</div>
<div>{{ photo.exif.LensModel }}</div>
</div>
<div class="uk-grid-small" uk-grid>
<div class="uk-width-expand" uk-leader>Shutter Speed</div>
<div class="uk-width-expand" uk-leader>{% trans "Shutter Speed" %}</div>
<div>{{ photo.exif.ExposureTime|exif_exposuretime }}</div>
</div>
<div class="uk-grid-small" uk-grid>
<div class="uk-width-expand" uk-leader>Aperture</div>
<div class="uk-width-expand" uk-leader>{% trans "Aperture" %}</div>
<div>{{ photo.exif.FNumber|exif_fnumber }}</div>
</div>
<div class="uk-grid-small" uk-grid>
<div class="uk-width-expand" uk-leader>ISO</div>
<div class="uk-width-expand" uk-leader>{% trans "ISO" %}</div>
<div>{{ photo.exif.ISOSpeedRatings|exif_isospeedratings }}</div>
</div>
<div class="uk-grid-small" uk-grid>
<div class="uk-width-expand" uk-leader>Focal Length</div>
<div class="uk-width-expand" uk-leader>{% trans "Focal Length" %}</div>
<div>{{ photo.exif.FocalLength|exif_focallength}}</div>
</div>
<div class="uk-grid-small" uk-grid>
<div class="uk-width-expand" uk-leader>Focal Length in 35mm</div>
<div class="uk-width-expand" uk-leader>{% trans "Focal Length in 35mm" %}</div>
<div>{{ photo.exif.FocalLengthIn35mmFilm|exif_focallength }}</div>
</div>
<div class="uk-grid-small" uk-grid>
<div class="uk-width-expand" uk-leader>Keywords</div>
<div class="uk-width-expand" uk-leader>{% trans "Keywords" %}</div>
<div>{{ photo.exif.Keywords|exif_keywords }}</div>
</div>
</div>

View file

@ -1,8 +1,9 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
<!-- Title -->
{% block title %} Photostream {% endblock %}
{% block title %} {% trans "Photostream" %} {% endblock %}
<!-- Parallax -->
{% block parallax %}
@ -18,46 +19,28 @@
<div class="uk-flex uk-flex-between uk-flex-wrap uk-flex-middle">
<!-- Breadcrumb -->
<ul class="uk-breadcrumb uk-margin-remove uk-flex uk-flex-middle">
<li class="uk-visible@m"><a href="{% url 'gallery:main_url' %}">Home</a></li>
<li class="uk-visible@m uk-disabled"><a>Photostream</a></li>
<li class="uk-visible@m"><a href="{% url 'gallery:main_url' %}">{% trans "Home" %}</a></li>
<li class="uk-visible@m uk-disabled"><a>{% trans "Photostream" %}</a></li>
</ul>
<!-- Sort menu -->
<ul class="uk-subnav uk-subnav-divider uk-margin-remove uk-flex uk-flex-middle uk-margin-medium-top@s">
<li {% if order == 'latest' %}class="uk-active"{% endif %}>
<a href="{% search_link 'latest' request.GET %}">Latest</a>
<a href="{% search_link 'latest' request.GET %}">{% trans "Latest" %}</a>
</li>
<li {% if order == 'liked' %}class="uk-active"{% endif %}>
<a href="{% search_link 'liked' request.GET %}">Liked</a>
<a href="{% search_link 'liked' request.GET %}">{% trans "Liked" %}</a>
</li>
<li {% if order == 'popular' %}class="uk-active"{% endif %}>
<a href="{% search_link 'popular' request.GET %}">Popular</a>
<a href="{% search_link 'popular' request.GET %}">{% trans "Popular" %}</a>
</li>
</ul>
</div>
</div>
<div class="uk-grid-small uk-child-width-1-2 uk-child-width-1-3@s uk-child-width-1-4@m uk-child-width-1-5@l" uk-grid="masonry: true">
{% for photo in object_list %}
<a href="{{ photo.get_absolute_url }}">
<img
loading="lazy"
src="{{ photo.photo_sm.url }}"
srcset="
{{ photo.photo_sm.url }} 320w,
{{ photo.photo_md.url }} 720w,
{{ photo.photo_bg.url }} 1920w
"
sizes="(max-width: 640px) 50vw,
(max-width: 960px) 33vw,
(max-width: 1200px) 25vw,
20vw"
width="{{ photo.width }}"
height="{{ photo.height }}"
style="aspect-ratio: {{ photo.aspect_ratio }};"
alt="{{ photo.album.name }} - {{ photo.slug }}">
</a>
{% include "gallery/partials/photo_thumbnail.html" with photo=photo %}
{% endfor %}
</div>

View file

@ -2,10 +2,11 @@
<html lang="en">
<head>
{% load static %}
{% load i18n %}
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Muistox Photo Gallery">
<title>Slideshow : {{ photo.album.name }} - Gallery</title>
<meta name="description" content="{% trans "Muistox Photo Gallery" %}">
<title>{% trans "Slideshow" %} : {{ photo.album.name }} - {% trans "Gallery" %} </title>
{% if next_photo %}
<meta http-equiv="refresh" content="5; url={% url 'gallery:photo_slideshow_url' next_photo.album.slug next_photo.slug %}" />
{% endif %}

View file

@ -0,0 +1,149 @@
# Muistox galleria en käännökset.
# Copyright (C) 2025 Nyymix
# This file is distributed under the same license as the muistox package.
# Nyymix <nyymix@gmail.com>, 2025.
#
msgid ""
msgstr ""
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "Gallery"
msgstr ""
msgid "Home"
msgstr ""
msgid "Albums"
msgstr ""
msgid "Photostream"
msgstr ""
msgid "About"
msgstr ""
msgid "Admin"
msgstr ""
msgid "Search"
msgstr ""
msgid "Slideshow"
msgstr ""
msgid "Muistox Photo Gallery"
msgstr ""
msgid "Search albums"
msgstr ""
msgid "Latest"
msgstr ""
msgid "Liked"
msgstr ""
msgid "Popular"
msgstr ""
msgid "%(photo_count)s photo"
msgid_plural "%(photo_count)s photos"
msgstr[0] ""
msgstr[1] ""
msgid "%(view_count)s view"
msgid_plural "%(view_count)s views"
msgstr[0] ""
msgstr[1] ""
msgid "Photo Info"
msgstr ""
msgid "Album"
msgstr ""
msgid "Photo Name"
msgstr ""
msgid "Photo Taken"
msgstr ""
msgid "Views"
msgstr ""
msgid "Likes"
msgstr ""
msgid "Download"
msgstr ""
msgid "Like"
msgstr ""
msgid "Exif"
msgstr ""
msgid "Camera"
msgstr ""
msgid "Lens"
msgstr ""
msgid "Shutter Speed"
msgstr ""
msgid "Aperture"
msgstr ""
msgid "ISO"
msgstr ""
msgid "Focal Length"
msgstr ""
msgid "Focal Length in 35mm"
msgstr ""
msgid "Keywords"
msgstr ""
msgid "Prev"
msgstr ""
msgid "Next"
msgstr ""
msgid "%(public_count)s public"
msgid_plural "%(public_count)s public"
msgstr[0] "%(public_count)s public"
msgstr[1] "%(public_count)s public"
msgid "album"
msgid_plural "albums"
msgstr[0] ""
msgstr[1] ""
msgid "photo"
msgid_plural "photos"
msgstr[0] ""
msgstr[1] ""
msgid "Contact"
msgstr ""
msgid "Muistox gallery"
msgstr ""
msgid "Just another wannabe photographer..."
msgstr ""
msgid "Events photography"
msgstr ""
msgid "Nyymix.net Gallery"
msgstr ""

View file

@ -0,0 +1,149 @@
# Muistox galleria fi käännökset.
# Copyright (C) 2025 Nyymix
# This file is distributed under the same license as the muistox package.
# Nyymix <nyymix@gmail.com>, 2025.
#
msgid ""
msgstr ""
"Language: fi\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "Gallery"
msgstr "Galleria"
msgid "Home"
msgstr "Etusivu"
msgid "Albums"
msgstr "Albumit"
msgid "Photostream"
msgstr "Valokuvat"
msgid "About"
msgstr "Tietoja"
msgid "Admin"
msgstr "Ylläpito"
msgid "Search"
msgstr "Haku"
msgid "Slideshow"
msgstr "Diaesitys"
msgid "Muistox Photo Gallery"
msgstr "Muistox kuvagalleria"
msgid "Search albums"
msgstr "Hae albumeita"
msgid "Latest"
msgstr "Uusimmat"
msgid "Liked"
msgstr "Tykätyimmät"
msgid "Popular"
msgstr "Katsotuimmat"
msgid "%(photo_count)s photo"
msgid_plural "%(photo_count)s photos"
msgstr[0] "%(photo_count)s kuva"
msgstr[1] "%(photo_count)s kuvaa"
msgid "%(view_count)s view"
msgid_plural "%(view_count)s views"
msgstr[0] "%(view_count)s näyttökerta"
msgstr[1] "%(view_count)s näyttökertaa"
msgid "Photo Info"
msgstr "Valokuvan tiedot"
msgid "Album"
msgstr "Albumi"
msgid "Photo Name"
msgstr "Valokuvan nimi"
msgid "Photo Taken"
msgstr "Valokuva otettu"
msgid "Views"
msgstr "Katselukerrat"
msgid "Likes"
msgstr "Tykkäykset"
msgid "Download"
msgstr "Lataa"
msgid "Like"
msgstr "Tykkää"
msgid "Exif"
msgstr "Exif"
msgid "Camera"
msgstr "Kamera"
msgid "Lens"
msgstr "Linssi"
msgid "Shutter Speed"
msgstr "Suljinaika"
msgid "Aperture"
msgstr "Aukko"
msgid "ISO"
msgstr "ISO"
msgid "Focal Length"
msgstr "Polttoväli"
msgid "Focal Length in 35mm"
msgstr "Polttoväli (35 mm kinovastaavuus)"
msgid "Keywords"
msgstr "Avainsanat"
msgid "Prev"
msgstr "Edellinen"
msgid "Next"
msgstr "Seuraava"
msgid "%(public_count)s public"
msgid_plural "%(public_count)s public"
msgstr[0] "%(public_count)s julkinen"
msgstr[1] "%(public_count)s julkista"
msgid "album"
msgid_plural "albums"
msgstr[0] "albumi"
msgstr[1] "albumia"
msgid "photo"
msgid_plural "photos"
msgstr[0] "kuva"
msgstr[1] "kuvaa"
msgid "Contact"
msgstr "Ota yhteyttä"
msgid "Muistox gallery"
msgstr "Muistox Kuvagalleria"
msgid "Just another wannabe photographer..."
msgstr "Taas yksi, joka luulee olevansa valokuvaaja..."
msgid "Events photography"
msgstr "Tapahtumavalokuvausta"
msgid "Nyymix.net Gallery"
msgstr "Nyymix.net Kuvagalleria"

View file

@ -3,6 +3,7 @@
<head>
{% load static %}
{% load i18n %}
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Muistox Photo Gallery">
@ -32,21 +33,21 @@
<div class="uk-navbar-left uk-margin-left">
<ul class="uk-navbar-nav">
<li><a href="{% url 'gallery:main_url' %}"><span uk-icon="camera"></span></a></li>
<li class="uk-visible@m"><a href="{% url 'gallery:albums_url' %}">Albums</a></li>
<li class="uk-visible@m"><a href="{% url 'gallery:photos_url' %}">Photostream</a></li>
<li class="uk-visible@m"><a href="{% url 'gallery:albums_url' %}">{% trans "Albums" %}</a></li>
<li class="uk-visible@m"><a href="{% url 'gallery:photos_url' %}">{% trans "Photostream" %}</a>
</ul>
</div>
<div class="uk-navbar-right uk-margin-right">
<div class="uk-navbar-item uk-visible@m">
<form class="uk-search uk-search-default" action="{% url 'gallery:search_url' %}" method="get">
<a href="" class="uk-search-icon-flip" uk-search-icon></a>
<input id="q" name="q" class="uk-search-input uk-form-width-small" type="search" placeholder="Search albums" aria-label="Search">
<input id="q" name="q" class="uk-search-input uk-form-width-small" type="search" placeholder="{% translate 'Search albums' %}" aria-label="{% translate 'Search' %}">
</form>
</div>
<ul class="uk-navbar-nav">
<li class="uk-visible@m"><a href="{% url 'gallery:about_url' %}">About</a></li>
<li class="uk-visible@m"><a href="{% url 'gallery:about_url' %}">{% trans "About" %}</a></li>
{% if user.is_authenticated %}
<li class="uk-visible@m"><a href="{% url 'admin:index' %}">Admin</a></li>
<li class="uk-visible@m"><a href="{% url 'admin:index' %}">{% trans "Admin" %}</a></li>
{% endif %}
<li class="uk-hidden@m"><a class="uk-navbar-toggle" uk-navbar-toggle-icon uk-toggle="target: #offcanvas-nav"></a></li>
</ul>
@ -61,15 +62,15 @@
<!-- MOBILE HAKU -->
<form class="uk-search uk-search-default uk-margin-small-bottom" action="{% url 'gallery:search_url' %}" method="get">
<a href="" class="uk-search-icon-flip" uk-search-icon></a>
<input id="q-mobile" name="q" class="uk-search-input" type="search" placeholder="Search albums" aria-label="Search">
<input id="q-mobile" name="q" class="uk-search-input" type="search" placeholder="{% translate 'Search albums' %}" aria-label="{% translate 'Search' %}">
</form>
<ul class="uk-nav uk-nav-default">
<li><a href="{% url 'gallery:main_url' %}">Home</a></li>
<li><a href="{% url 'gallery:albums_url' %}">Albums</a></li>
<li><a href="{% url 'gallery:photos_url' %}">Photostream</a></li>
<li><a href="{% url 'gallery:about_url' %}">About</a></li>
<li><a href="{% url 'gallery:main_url' %}">{% trans "Home" %}</a></li>
<li><a href="{% url 'gallery:albums_url' %}">{% trans "Albums" %}</a></li>
<li><a href="{% url 'gallery:photos_url' %}">{% trans "Photostream" %}</a></li>
<li><a href="{% url 'gallery:about_url' %}">{% trans "About" %}</a></li>
{% if user.is_authenticated %}
<li><a href="{% url 'admin:index' %}">Admin</a></li>
<li><a href="{% url 'admin:index' %}">{% trans "Admin" %}</a></li>
{% endif %}
</ul>
</div>