diff --git a/Dockerfile b/Dockerfile
index 58e008b7..3369c318 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -31,6 +31,7 @@ COPY --from=build --chown=django:django /root/.local /home/django/.local
RUN apt-get update && apt-get install -y \
default-mysql-client \
+ mime-support \
libmariadb3
USER django
@@ -41,6 +42,5 @@ ENV PROJECT_ROOT=/srv
ENV TEMPLATE_DIR=/srv/templates
COPY --chown=django:django scripts/ agagd/ /srv/
-RUN SECRET_KEY=stub-for-build python manage.py collectstatic --noinput
CMD ["/srv/entrypoint.sh"]
diff --git a/agagd/agagd/settings/base.py b/agagd/agagd/settings/base.py
index d20cf500..cda27ff9 100644
--- a/agagd/agagd/settings/base.py
+++ b/agagd/agagd/settings/base.py
@@ -79,10 +79,10 @@
STATICFILES_FINDERS = (
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
- # 'django.contrib.staticfiles.finders.DefaultStorageFinder',
+ "django.contrib.staticfiles.finders.DefaultStorageFinder",
)
-MIDDLEWARE = (
+MIDDLEWARE = [
"django.middleware.common.CommonMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
@@ -90,7 +90,7 @@
"django.contrib.messages.middleware.MessageMiddleware",
# Uncomment the next line for simple clickjacking protection:
"django.middleware.clickjacking.XFrameOptionsMiddleware",
-)
+]
ROOT_URLCONF = "agagd.urls"
@@ -123,11 +123,31 @@
# 'django.template.loaders.eggs.Loader',
],
},
- }
+ },
+ {
+ "BACKEND": "django.template.backends.jinja2.Jinja2",
+ "DIRS": [os.path.join(PROJECT_ROOT, "jinja2")],
+ "OPTIONS": {
+ "environment": "agagd_core.jinga2.environment",
+ "context_processors": [
+ # Standard context_processors
+ "django.contrib.auth.context_processors.auth",
+ "django.template.context_processors.debug",
+ "django.template.context_processors.i18n",
+ "django.template.context_processors.media",
+ "django.template.context_processors.static",
+ "django.template.context_processors.tz",
+ "django.contrib.messages.context_processors.messages",
+ # Custom context_processors
+ "django.template.context_processors.request",
+ "agagd_core.context_processors.google_analytics_tracking_id",
+ ],
+ },
+ },
]
-INSTALLED_APPS = (
+INSTALLED_APPS = [
"agagd_core",
"django.contrib.auth",
"django.contrib.contenttypes",
@@ -136,7 +156,7 @@
"django.contrib.messages",
"django.contrib.staticfiles",
"django_tables2",
-)
+]
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
diff --git a/agagd/agagd/settings/prod.py b/agagd/agagd/settings/prod.py
index 65917406..6cbe8692 100644
--- a/agagd/agagd/settings/prod.py
+++ b/agagd/agagd/settings/prod.py
@@ -4,9 +4,31 @@
if os.getenv("DEBUG") == "true":
DEBUG = True
+
+ # DebugToolbar Middleware
+ MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"]
+
+ # DebugToobar
+ INSTALLED_APPS += ["debug_toolbar"]
+
+ # Add our Docker host IP to the INTERNAL_IPS
+ import os
+ import socket
+
+ HOSTNAME = os.getenv("HOSTNAME")
+ INTERNAL_IPS = ["127.0.0.1", socket.gethostbyname(HOSTNAME)]
+
+ # DebugToolbar Configurations
+ DEBUG_TOOLBAR_CONFIG = {
+ "INTERCEPT_REDIRECTS": False,
+ "SHOW_COLLAPSED": True,
+ "SHOW_TOOLBAR_CALLBACK": lambda request: DEBUG,
+ }
+
else:
DEBUG = False
+
GOOGLE_ANALYTICS_TRACKING_ID = os.getenv("GOOGLE_ANALYTICS_TRACKING_ID", "")
ADMIN_ENABLED = False
@@ -21,7 +43,6 @@
_dbname = os.getenv("APP_DB_NAME", "")
_dbhost = os.getenv("DB_HOST", "")
_dbport = os.getenv("DB_PORT", "")
-_templates = os.getenv("TEMPLATE_DIR", os.path.join(PROJECT_ROOT, "templates"))
SECRET_KEY = _key
@@ -35,5 +56,3 @@
"PORT": _dbport, # Set to empty string for default. Not used with sqlite3.
}
}
-
-TEMPLATES[0]["DIRS"] = [_templates]
diff --git a/agagd/agagd/urls.py b/agagd/agagd/urls.py
index 2399751b..f292ca4c 100644
--- a/agagd/agagd/urls.py
+++ b/agagd/agagd/urls.py
@@ -7,7 +7,7 @@
from django.urls import path, reverse_lazy
from django.views.generic import RedirectView
-urlpatterns = (
+urlpatterns = [
url(r"^$", agagd_views.index, name="index"),
url(r".php$", RedirectView.as_view(url=reverse_lazy("index"))),
url(r"^search/$", agagd_views.search, name="search"),
@@ -61,4 +61,10 @@
path("qualifications/", QualificationsPageView.as_view()),
# Beta
path("beta/", include(beta_urls.beta_patterns)),
-)
+]
+
+# DebugToolbar URL Configuration
+if settings.DEBUG:
+ import debug_toolbar
+
+ urlpatterns = [path("__debug__/", include(debug_toolbar.urls))] + urlpatterns
diff --git a/agagd/agagd_core/jinga2.py b/agagd/agagd_core/jinga2.py
new file mode 100644
index 00000000..d0096005
--- /dev/null
+++ b/agagd/agagd_core/jinga2.py
@@ -0,0 +1,28 @@
+import agagd_core.models as agagd_models
+from django.core.exceptions import ObjectDoesNotExist
+from django.templatetags.static import static
+from django.urls import reverse
+from jinja2 import Environment
+
+
+def get_members_name_and_id(value):
+ """
+ Provides jinja2 custom filter which returns
+ the members information as
+ "[member's full name] (member_id)".
+ """
+ try:
+ member = agagd_models.Member.objects.values("full_name", "member_id").get(
+ pk=value
+ )
+ except ObjectDoesNotExist:
+ raise ("Member {value} does not exist.")
+
+ return f"{member['full_name']} ({member['member_id']})"
+
+
+def environment(**options):
+ env = Environment(**options)
+ env.filters["get_members_name_and_id"] = get_members_name_and_id
+ env.globals.update({"static": static, "url": reverse})
+ return env
diff --git a/agagd/agagd_core/tables/beta.py b/agagd/agagd_core/tables/beta.py
deleted file mode 100644
index 7aa43ca0..00000000
--- a/agagd/agagd_core/tables/beta.py
+++ /dev/null
@@ -1,362 +0,0 @@
-# AGAGD Models Imports
-import agagd_core.models as agagd_models
-
-# Django Imports
-import django_tables2 as tables
-from django.core.exceptions import ObjectDoesNotExist
-from django.urls import reverse
-from django.utils.safestring import mark_safe
-
-
-class WinnerColumn(tables.Column):
- def __init__(
- self,
- color="W",
- viewname=None,
- urlconf=None,
- args=None,
- kwargs=None,
- current_app=None,
- attrs=None,
- **extra
- ):
- super().__init__(
- attrs=attrs,
- linkify=dict(
- viewname=viewname,
- urlconf=urlconf,
- args=args,
- kwargs=kwargs,
- current_app=current_app,
- ),
- **extra
- )
- self.color = color
-
- def render(self, value, record):
- if record.result == self.color:
- self.attrs["td"] = {"class": "winner"}
- else:
- self.attrs["td"] = {"class": "runner-up"}
- return value
-
-
-class ChapterColumn(tables.Column):
- # Takes a chapter ID and produces an href with the chapter's name
- def render(self, value):
- try:
- members_chapter = agagd_models.Chapters.objects.get(member_id=value)
-
- chapter_url = reverse(
- viewname="chapter_detail", kwargs={"chapter_id": value}
- )
-
- chapter_name = members_chapter.name
- if chapter_name is None or chapter_name == "":
- chapter_name = members_chapter.code
-
- chapter_html = mark_safe(
- "{}".format(chapter_url, chapter_name)
- )
- except:
- chapter_html = u"\u2014"
-
- return chapter_html
-
-
-# Standard GameTable display as is on agagd.usgo.org and most pages
-class GameTable(tables.Table):
- game_date = tables.Column(
- verbose_name="Date",
- attrs={
- "th": {"class": "d-none d-lg-table-cell d-xl-table-cell"},
- "td": {"class": "d-none d-lg-table-cell d-xl-table-cell"},
- },
- )
- handicap = tables.Column(
- attrs={
- "th": {"class": "d-none d-lg-table-cell d-xl-table-cell"},
- "td": {"class": "d-none d-lg-table-cell d-xl-table-cell"},
- }
- )
- pin_player_1 = WinnerColumn(
- color="W",
- viewname="member_detail",
- verbose_name="White",
- kwargs={"member_id": tables.A("pin_player_1.member_id")},
- )
- pin_player_2 = WinnerColumn(
- color="B",
- viewname="member_detail",
- verbose_name="Black",
- kwargs={"member_id": tables.A("pin_player_2.member_id")},
- )
- tournament_code = tables.LinkColumn(
- verbose_name="Tournament",
- viewname="tournament_detail",
- kwargs={"tourn_code": tables.A("tournament_code.tournament_code")},
- )
-
- class Meta:
- model = agagd_models.Game
- attrs = {"class": "table", "thead": {"class": "thead-light"}}
- fields = (
- "game_date",
- "tournament_code",
- "pin_player_1",
- "pin_player_2",
- "round",
- "handicap",
- "komi",
- )
- sequence = fields
- template_name = "django_tables2/bootstrap4.html"
-
-
-# Alternative GameTable
-#
-# Displays GameTable without the Tournament Name Column
-#
-# References:
-# GitHubIssue#20
-class SecondaryGameTable(GameTable):
- tournament_code = None
-
- class Meta:
- model = agagd_models.Game
- fields = (
- "game_date",
- "round",
- "pin_player_1",
- "pin_player_2",
- "handicap",
- "komi",
- )
- sequence = fields
- template_name = "django_tables2/bootstrap4.html"
-
-
-class OpponentTable(tables.Table):
- def __init__(self, qs, p1, *args, **kwargs):
- self.this_player = p1
- tables.Table.__init__(self, qs)
-
- empty_text = "Opponent information couldn't be calculated"
- opponent = tables.LinkColumn(
- "member_detail", kwargs={"member_id": tables.A("opponent.member_id")}
- )
- total = tables.Column(verbose_name="Games")
- won = tables.Column(verbose_name="Won", default=0)
- lost = tables.Column(verbose_name="Lost")
- ratio = tables.Column(
- verbose_name="Rate", default=0, empty_values=(-1,), orderable=False
- )
-
- def render_ratio(self, record):
- return "{:.2f}".format(record["won"] / record["total"])
-
- class Meta:
- attrs = {"class": "table", "thead": {"class": "thead-light"}}
- order_by = ("-total", "-won")
- template_name = "django_tables2/bootstrap4.html"
-
-
-class MemberTable(tables.Table):
- member_id = tables.LinkColumn(
- "member_detail", kwargs={"member_id": tables.A("member_id")}
- )
- chapter_id = ChapterColumn(verbose_name="Chapter")
- players__rating = tables.Column(verbose_name="Rating")
- country = tables.LinkColumn(
- "country_detail", kwargs={"country_name": tables.A("country")}
- )
- full_name = tables.LinkColumn(
- "member_detail", kwargs={"member_id": tables.A("member_id")}
- )
-
- class Meta:
- model = agagd_models.Member
- attrs = {"class": "table", "thead": {"class": "thead-light"}}
- fields = ("full_name", "state", "players__rating", "renewal_due", "country")
- sequence = (
- "full_name",
- "players__rating",
- "chapter_id",
- "country",
- "state",
- "renewal_due",
- "member_id",
- )
- template_name = "django_tables2/bootstrap4.html"
-
-
-class ChapterMemberTable(MemberTable):
- class Meta:
- model = agagd_models.Member
- attrs = {"class": "table", "thead": {"class": "thead-light"}}
- fields = ("full_name", "state", "players__rating", "renewal_due", "country")
- sequence = (
- "full_name",
- "players__rating",
- "country",
- "state",
- "renewal_due",
- "member_id",
- )
- template_name = "django_tables2/bootstrap4.html"
-
-
-class TopDanTable(tables.Table):
- member_id = tables.LinkColumn(
- "member_detail", kwargs={"member_id": tables.A("member_id")}
- )
- full_name = tables.LinkColumn(
- "member_detail", kwargs={"member_id": tables.A("member_id")}
- )
-
- class Meta:
- model = agagd_models.TopDan
- attrs = {"class": "table", "thead": {"class": "thead-light"}}
- fields = ("member_id", "full_name", "rating")
- sequence = fields
- template_name = "django_tables2/bootstrap4.html"
-
-
-class TopKyuTable(tables.Table):
- member_id = tables.LinkColumn(
- "member_detail", kwargs={"member_id": tables.A("member_id")}
- )
- full_name = tables.LinkColumn(
- "member_detail", kwargs={"member_id": tables.A("member_id")}
- )
-
- class Meta:
- model = agagd_models.TopKyu
- attrs = {"class": "table", "thead": {"class": "thead-light"}}
- fields = ("member_id", "full_name", "rating")
- sequence = fields
- template_name = "django_tables2/bootstrap4.html"
-
-
-class MostRatedGamesPastYearTable(tables.Table):
- member_id = tables.LinkColumn(
- "member_detail", kwargs={"member_id": tables.A("member_id")}
- )
- name = tables.LinkColumn(
- "member_detail", kwargs={"member_id": tables.A("member_id")}
- )
- total = tables.Column()
-
- class Meta:
- model = agagd_models.MostRatedGamesPastYear
- attrs = {"class": "table", "thead": {"class": "thead-light"}}
- fields = ("member_id", "name", "total")
- sequence = fields
- template_name = "django_tables2/bootstrap4.html"
-
-
-class MostTournamentsPastYearTable(tables.Table):
- member_id = tables.LinkColumn(
- "member_detail", kwargs={"member_id": tables.A("member_id")}
- )
- name = tables.LinkColumn(
- "member_detail", kwargs={"member_id": tables.A("member_id")}
- )
-
- class Meta:
- model = agagd_models.MostTournamentsPastYear
- attrs = {"class": "table", "thead": {"class": "thead-light"}}
- fields = ("member_id", "name", "total")
- sequence = fields
- template_name = "django_tables2/bootstrap4.html"
-
-
-class AllPlayerRatingsTable(tables.Table):
- full_name = tables.LinkColumn(
- "member_detail", kwargs={"member_id": tables.A("member_id")}
- )
- member_id = tables.LinkColumn(
- "member_detail", kwargs={"member_id": tables.A("member_id")}
- )
- type = tables.Column()
- players__rating = tables.Column()
- chapter_id = ChapterColumn(verbose_name="Chapter")
- state = tables.Column()
- players__sigma = tables.Column(verbose_name="Sigma")
-
- class Meta:
- attrs = {"class": "table", "thead": {"class": "thead-light"}}
- fields = (
- "full_name",
- "member_id",
- "players__rating",
- "players__sigma",
- "type",
- "chapter_id",
- "state",
- )
- sequence = fields
- template_name = "django_tables2/bootstrap4.html"
-
-
-class TournamentTable(tables.Table):
- tournament_date = tables.Column(
- verbose_name="Date",
- attrs={
- "th": {"class": "d-none d-lg-table-cell d-xl-table-cell"},
- "td": {"class": "d-none d-lg-table-cell d-xl-table-cell"},
- },
- )
- tournament_code = tables.LinkColumn(
- "tournament_detail",
- verbose_name="Code",
- kwargs={"tourn_code": tables.A("tournament_code")},
- )
- total_players = tables.Column(
- verbose_name="# Players",
- attrs={
- "th": {"class": "d-none d-lg-table-cell d-xl-table-cell"},
- "td": {"class": "d-none d-lg-table-cell d-xl-table-cell"},
- },
- )
- elab_date = tables.Column(
- verbose_name="Rated",
- attrs={
- "th": {"class": "d-none d-lg-table-cell d-xl-table-cell"},
- "td": {"class": "d-none d-lg-table-cell d-xl-table-cell"},
- },
- )
-
- class Meta:
- model = agagd_models.Tournament
- attrs = {
- "class": "table",
- "thead": {"class": "thead-light"},
- "th": {"scope": "col"},
- }
- fields = (
- "tournament_date",
- "tournament_code",
- "description",
- "city",
- "state",
- "total_players",
- "rounds",
- "elab_date",
- )
- sequence = fields
- template_name = "django_tables2/bootstrap4.html"
-
-
-class TournamentPlayedTable(tables.Table):
- tournament = tables.LinkColumn(
- "tournament_detail", kwargs={"tourn_code": tables.A("tournament.pk")}
- )
- date = tables.Column(default="Unknown")
- won = tables.Column(verbose_name="Won", default=0)
- lost = tables.Column(verbose_name="Lost", default=0)
- # Steve note for issue #122 here
-
- class Meta:
- attrs = {"class": "table", "thead": {"class": "thead-light"}}
- template_name = "django_tables2/bootstrap4.html"
diff --git a/agagd/agagd_core/urls.py b/agagd/agagd_core/urls.py
index 9064b6cb..67b58693 100644
--- a/agagd/agagd_core/urls.py
+++ b/agagd/agagd_core/urls.py
@@ -6,4 +6,6 @@
beta_patterns = ([
path('', beta.index, name='index'),
path('players/', beta.list_all_players, name='players_list'),
+ path('tournaments/', beta.list_all_tournaments, name='tournaments_list'),
+ path('tournaments//', beta.tournament_detail, name='tournament_detail')
], 'beta')
diff --git a/agagd/agagd_core/views/beta.py b/agagd/agagd_core/views/beta.py
index c827953d..76c39ab6 100644
--- a/agagd/agagd_core/views/beta.py
+++ b/agagd/agagd_core/views/beta.py
@@ -4,9 +4,6 @@
# AGAGD Models Import
import agagd_core.models as agagd_models
-# AGAGD Tables Import
-import agagd_core.tables.beta as agagd_tables
-
# Django Imports
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.db.models import F, Q
@@ -34,37 +31,130 @@ def agagd_paginator_helper(
def index(request):
- game_list = agagd_models.Game.objects.filter(
- game_date__gte=datetime.now() - timedelta(days=180)
- ).order_by("-game_date")
- table = agagd_tables.GameTable(game_list, prefix="games")
- topDanList = agagd_models.TopDan.objects.values()
- topDanTable = agagd_tables.TopDanTable(topDanList)
- topKyuList = agagd_models.TopKyu.objects.values()
- topKyuTable = agagd_tables.TopKyuTable(topKyuList)
- mostRatedGamesPastYearList = agagd_models.MostRatedGamesPastYear.objects.values()
- mostRatedGamesTable = agagd_tables.MostRatedGamesPastYearTable(
- mostRatedGamesPastYearList
+ default_mobile_column_attrs = "d-none d-lg-table-cell d-xl-table-cell"
+
+ latest_games_table_headers = {
+ "game_date": "Date",
+ "tournament_code_id": "Tournament Code",
+ "pin_player_1": "White",
+ "pin_player_2": "Black",
+ "handicap": "Handicap",
+ "komi": "Komi",
+ }
+
+ latest_games_mobile_columns = {
+ "handicap": default_mobile_column_attrs,
+ "komi": default_mobile_column_attrs,
+ }
+
+ latest_games = agagd_models.Game.objects.values(
+ "game_date",
+ "tournament_code_id",
+ "pin_player_1",
+ "pin_player_2",
+ "handicap",
+ "komi",
+ ).order_by("-game_date")[:25]
+
+ latest_tournaments_table_headers = {
+ "tournament_date": "Date",
+ "elab_date": "Rated",
+ "tournament_code": "Tournament Code",
+ "city": "City",
+ "state": "State",
+ "rounds": "Rounds",
+ }
+
+ latest_tournaments_mobile_columns = {
+ "city": default_mobile_column_attrs,
+ "state": default_mobile_column_attrs,
+ "rounts": default_mobile_column_attrs,
+ }
+
+ latest_tournaments = agagd_models.Tournament.objects.values(
+ "tournament_date", "elab_date", "tournament_code", "city", "state", "rounds"
+ ).order_by("-elab_date")[:25]
+
+ top_10_kyu_dan_table_headers = {
+ "pin_player": "Player",
+ "rating": "Rating",
+ "sigma": "Sigma",
+ }
+
+ top_10_dan_kyu = agagd_models.Players.objects.values(
+ "pin_player", "rating", "sigma"
)
- mostTournamentsPastYearList = agagd_models.MostTournamentsPastYear.objects.values()
- mostTournamentsPastYearTable = agagd_tables.MostTournamentsPastYearTable(
- mostTournamentsPastYearList
+
+ top_10_dan = top_10_dan_kyu.filter(rating__gt=0).order_by("-rating")[:10]
+
+ top_10_kyu = top_10_dan_kyu.filter(rating__lt=0).order_by("-rating")[:10]
+
+ return render(
+ request,
+ "beta.index.html",
+ {
+ "latest_games": latest_games,
+ "latest_tournaments": latest_tournaments,
+ "top_10_dan": top_10_dan,
+ "top_10_kyu": top_10_kyu,
+ "latest_games_table_headers": latest_games_table_headers,
+ "latest_tournaments_table_headers": latest_tournaments_table_headers,
+ "top_10_kyu_dan_table_headers": top_10_kyu_dan_table_headers,
+ "latest_games_mobile_columns": latest_games_mobile_columns,
+ "latest_tournaments_mobile_columns": latest_tournaments_mobile_columns,
+ },
)
- RequestConfig(request).configure(table)
- tourneys = agagd_models.Tournament.objects.all().order_by("-tournament_date")
- t_table = agagd_tables.TournamentTable(tourneys, prefix="tourneys")
- RequestConfig(request, paginate={"per_page": 10}).configure(t_table)
+
+
+def tournament_detail(request, code):
+ try:
+ tournament = agagd_models.Tournament.objects.get(pk=code)
+ except Tournament.DoesNotExist:
+ raise Http404(f"Tournament {name} does not exist.")
+
+ tournament_information = {
+ "tournament_code": tournament.pk,
+ "description": tournament.description,
+ "elab_date": tournament.elab_date,
+ "tournament_date": tournament.tournament_date,
+ "state": tournament.state,
+ }
+
+ tournament_table_headers = {
+ "tournament_code": "Code",
+ "description": "Description",
+ "tournament_date": "Date",
+ "elab_date": "Rated",
+ "city": "City",
+ "state": "State",
+ "rounds": "Rounds",
+ "total_players": "No. Players",
+ }
+
+ tournament_games = agagd_paginator_helper(
+ request,
+ tournament.games_in_tourney.values(
+ "game_date", "pin_player_1", "pin_player_2", "handicap", "komi"
+ ),
+ )
+
+ tournament_game_table_headers = {
+ "game_date": "Date",
+ "pin_player_1": "White",
+ "pin_player_2": "Black",
+ "handicap": "Handicap",
+ "komi": "Komi",
+ }
return render(
request,
- "agagd_core/index.beta.html",
+ "beta.tournament_detail.html",
{
- "table": table,
- "top_dan_table": topDanTable,
- "top_kyu_table": topKyuTable,
- "most_rated_games_table": mostRatedGamesTable,
- "most_tournaments_table": mostTournamentsPastYearTable,
- "tournaments": t_table,
+ "page_title": tournament_information["tournament_code"],
+ "tournament_information": tournament_information,
+ "tournament_games": tournament_games,
+ "tournament_table_headers": tournament_table_headers,
+ "tournament_game_table_headers": tournament_game_table_headers,
},
)
@@ -108,7 +198,7 @@ def list_all_players(request):
return render(
request,
- "agagd_core/players_list.html",
+ "beta.players_list.html",
{
"mobile_column_attrs": mobile_column_attrs,
"list_all_players_columns": list_all_players_columns,
@@ -116,3 +206,50 @@ def list_all_players(request):
"page_title": "Members Ratings",
},
)
+
+
+def list_all_tournaments(request):
+ mobile_column_default_attrs = "d-none d-lg-table-cell d-xl-table-cell"
+
+ mobile_columns = {
+ "city": mobile_column_default_attrs,
+ "state": mobile_column_default_attrs,
+ "total_players": mobile_column_default_attrs,
+ }
+
+ table_headers = {
+ "tournament_code": "Code",
+ "description": "Description",
+ "tournament_date": "Date",
+ "elab_date": "Rated",
+ "city": "City",
+ "state": "State",
+ "rounds": "Rounds",
+ "total_players": "No. Players",
+ }
+
+ list_all_tournaments_query = agagd_models.Tournament.objects.values(
+ "tournament_code",
+ "description",
+ "tournament_date",
+ "elab_date",
+ "city",
+ "state",
+ "rounds",
+ "total_players",
+ ).order_by("-tournament_date")
+
+ list_all_tournaments_with_pagination = agagd_paginator_helper(
+ request, list_all_tournaments_query
+ )
+
+ return render(
+ request,
+ "beta.tournaments_list.html",
+ {
+ "mobile_columns": mobile_columns,
+ "table_headers": table_headers,
+ "list_all_tournaments": list_all_tournaments_with_pagination,
+ "page_title": "Tournaments",
+ },
+ )
diff --git a/agagd/templates/base.beta.html b/agagd/jinja2/beta.base.html
similarity index 86%
rename from agagd/templates/base.beta.html
rename to agagd/jinja2/beta.base.html
index 8bca611d..4a308c22 100644
--- a/agagd/templates/base.beta.html
+++ b/agagd/jinja2/beta.base.html
@@ -1,13 +1,10 @@
-
-{% load static %}
-
{% block title %}
{% if page_title %}
- {{ "AGAGD | "|add:page_title }}
+ {{ "AGAGD | " ~ page_title }}
{% else %}
AGAGD | American Go Game Database
{% endif %}
@@ -44,7 +41,9 @@