Compare commits
3 Commits
1bf64a8b60
...
56f8309776
Author | SHA1 | Date |
---|---|---|
Ryan Rix | 56f8309776 | |
Ryan Rix | 36bd20f0d2 | |
Ryan Rix | b4c12058be |
121
arcology.org
121
arcology.org
|
@ -523,21 +523,7 @@ class FeedEntryAdmin(admin.ModelAdmin):
|
|||
|
||||
* The Web Server
|
||||
|
||||
"""arcology URL Configuration
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/3.2/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
These are the route [[https://docs.djangoproject.com/en/3.2/topics/http/urls/][urlpatterns]]:
|
||||
|
||||
#+begin_src python :tangle arcology/urls.py
|
||||
from django.contrib import admin
|
||||
|
@ -560,9 +546,11 @@ urlpatterns = [
|
|||
]
|
||||
#+end_src
|
||||
|
||||
This is the topmatter for the views described below:
|
||||
|
||||
#+begin_src python :tangle arcology/views.py
|
||||
import logging
|
||||
from django.http import HttpResponse, HttpResponseNotFound
|
||||
from django.http import HttpResponse, HttpResponseNotFound, Http404
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
|
||||
from arcology.models import Page, Feed, Site
|
||||
|
@ -573,16 +561,14 @@ from prometheus_client import Counter, Histogram
|
|||
logger = logging.getLogger(__name__)
|
||||
#+end_src
|
||||
|
||||
** NEXT =GET /= site index
|
||||
** =GET /= site index
|
||||
|
||||
this will just call the org-page rendering handler for the site's index pages eventually
|
||||
this will just call the Org Page rendering function for the site's index page. =render_page= is defined below.
|
||||
|
||||
#+begin_src python :tangle arcology/views.py
|
||||
def index(request):
|
||||
site = Site.from_request(request)
|
||||
|
||||
full_key = f"{site.key}/index"
|
||||
|
||||
return render_page(request, site, full_key)
|
||||
#+end_src
|
||||
|
||||
|
@ -594,7 +580,7 @@ def index(request):
|
|||
- State "INPROGRESS" from [2023-12-20 Wed 17:48]
|
||||
:END:
|
||||
|
||||
This constructs a page key, tries to load that page and its HTML, and renders that along with a bunch of other metadata.
|
||||
This constructs a page key from the request, tries to load that page and its HTML, and renders that along with a bunch of other metadata stored in relation to the =Page= object in the DB.
|
||||
|
||||
#+begin_src python :tangle arcology/views.py
|
||||
def org_page(request, key):
|
||||
|
@ -657,7 +643,7 @@ def render_page(request, site, full_key):
|
|||
))
|
||||
#+end_src
|
||||
|
||||
*** Rendering the converted Org HTML in to a whole web-page
|
||||
*** =arcology/page.html= extends =app.html= to embed the Org page and its metadata
|
||||
:PROPERTIES:
|
||||
:ID: 20240226T174503.655394
|
||||
:ROAM_ALIASES: "Arcology Page HTML Template"
|
||||
|
@ -783,7 +769,7 @@ Here's a really simple 404 template, too.
|
|||
:ROAM_ALIASES: "Arcology Page CSS Files"
|
||||
:END:
|
||||
|
||||
Most of the page CSS is defined below, but the content CSS is here, nearer the actual implementation of the flexbox:
|
||||
Most of the page CSS is defined below as part of the =app.html=, but the content-specific CSS is here, nearer the actual implementation of the flexbox above.
|
||||
|
||||
#+begin_src css :tangle arcology/static/arcology/css/app.css :mkdirp yes
|
||||
.content {
|
||||
|
@ -893,11 +879,16 @@ def feed(request, key):
|
|||
# Fetch page metadata
|
||||
the_feed = get_object_or_404(Feed, route_key=full_key)
|
||||
entries = the_feed.feedentry_set.order_by("-pubdate").all()[:10]
|
||||
|
||||
if len(entries) == 0:
|
||||
return Http404()
|
||||
|
||||
try:
|
||||
page_author = roam.models.Keyword.objects.get(keyword="AUTHOR", path=the_feed.file).value
|
||||
except roam.models.Keyword.DoesNotExist:
|
||||
logger.warn(f"Feed {key} does not have an AUTHOR!")
|
||||
page_author = "Arcology User"
|
||||
|
||||
page_url = the_feed.file.page_set.first().to_url()
|
||||
updated_at = arrow.get(entries[0].pubdate).format(arrow.FORMAT_RFC3339) # entries is already sorted
|
||||
|
||||
|
@ -971,7 +962,7 @@ def get_item(dictionary, key):
|
|||
- State "CANCELLED" from "NEXT" [2024-02-26 Mon 17:46]
|
||||
:END:
|
||||
|
||||
** NEXT unpublished/not found endpoint
|
||||
** 404 unpublished/not found endpoint
|
||||
|
||||
There are plenty of links inside the Arcology which aren't meant to be clicked. =roam:= stub links will of course
|
||||
|
||||
|
@ -991,7 +982,7 @@ def unpublished(request):
|
|||
)
|
||||
#+end_src
|
||||
|
||||
** =robots.txt= Endpoint
|
||||
** =GET /robots.txt= Endpoint
|
||||
|
||||
[[https://en.wikipedia.org/wiki/Robots.txt][robots.txt]] is the [[roam:Robots Exclusion Protocol]], a standard used by websites to indicate to visiting web crawlers and other web robots which portions of the website they are allowed to visit.
|
||||
|
||||
|
@ -1029,7 +1020,7 @@ Disallow: /
|
|||
{% endfor %}
|
||||
#+end_src
|
||||
|
||||
** Feed discovery endpoint
|
||||
** =GET /feeds.json= Feed discovery endpoint
|
||||
:LOGBOOK:
|
||||
CLOCK: [2024-02-15 Thu 14:17]--[2024-02-15 Thu 14:41] => 0:24
|
||||
:END:
|
||||
|
@ -1053,7 +1044,45 @@ def feed_list(request):
|
|||
return HttpResponse(json.dumps(ret), content_type="application/json")
|
||||
#+end_src
|
||||
|
||||
** Arcology Site Templates
|
||||
** =GET /sites.css= Per-Site link color dynamic CSS endpoint
|
||||
:PROPERTIES:
|
||||
:ID: 20231229T215425.830707
|
||||
:END:
|
||||
|
||||
This endpoint generates a dynamic CSS file that colorizes internal URLs based on the [[id:20231229T164611.256424][The Arcology's Site List]] which is stored in the database. It does something [[https://twitter.com/gotMLK7/status/1675994399086641152][extremely wicked]] to make the page links less jarring until you hover over them by faking an alpha-channel in to the color.
|
||||
|
||||
#+begin_src python :tangle arcology/views.py
|
||||
def site_css(request):
|
||||
sites = Site.objects.all()
|
||||
stanzas = []
|
||||
for site in sites:
|
||||
for domain in site.sitedomain_set.all():
|
||||
stanzas.append(f'''
|
||||
a[href*="//{domain.domain}"] {{
|
||||
border-radius: 0.25em;
|
||||
padding: 0.1em;
|
||||
background-color: {site.link_color}66;
|
||||
}}
|
||||
a[href*="//{domain.domain}"]:hover {{
|
||||
background-color: {site.link_color}FF !important;
|
||||
}}
|
||||
''')
|
||||
stanzas.append(f'''
|
||||
a[href*="/404"] {{
|
||||
color: var(--alert);
|
||||
/* text-decoration: line-through; */
|
||||
}}
|
||||
a[href*="/404"]::after {{
|
||||
content: " ⚠";
|
||||
}}
|
||||
a[href*="/404"]::before {{
|
||||
content: "⚠ ";
|
||||
}}
|
||||
''')
|
||||
return HttpResponse(stanzas, content_type="text/css")
|
||||
#+end_src
|
||||
|
||||
** =app.html= Arcology Site Templates
|
||||
|
||||
In short, there are four blocks that the page template and other templates will use to embed content in the rendered web page:
|
||||
- =title= is the =<title>= element, the name of the tab.
|
||||
|
@ -1286,43 +1315,9 @@ There are per-site CSS in [[id:20231229T164611.256424][The Arcology's Site List]
|
|||
(write-file "~/org/arcology-django/arcology/static/arcology/css/vulf.css"))
|
||||
#+end_src
|
||||
|
||||
** Per-Site link color dynamic CSS endpoint
|
||||
:PROPERTIES:
|
||||
:ID: 20231229T215425.830707
|
||||
:END:
|
||||
*** NEXT this is a lever for restructuring the arcology
|
||||
|
||||
This endpoint generates a dynamic CSS file that colorizes internal URLs based on the [[id:20231229T164611.256424][The Arcology's Site List]] which is stored in the database. It does something [[https://twitter.com/gotMLK7/status/1675994399086641152][extremely wicked]] to make the page links less jarring until you hover over them by faking an alpha-channel in to the color.
|
||||
|
||||
#+begin_src python :tangle arcology/views.py
|
||||
def site_css(request):
|
||||
sites = Site.objects.all()
|
||||
stanzas = []
|
||||
for site in sites:
|
||||
for domain in site.sitedomain_set.all():
|
||||
stanzas.append(f'''
|
||||
a[href*="//{domain.domain}"] {{
|
||||
border-radius: 0.25em;
|
||||
padding: 0.1em;
|
||||
background-color: {site.link_color}66;
|
||||
}}
|
||||
a[href*="//{domain.domain}"]:hover {{
|
||||
background-color: {site.link_color}FF !important;
|
||||
}}
|
||||
''')
|
||||
stanzas.append(f'''
|
||||
a[href*="/404"] {{
|
||||
color: var(--alert);
|
||||
/* text-decoration: line-through; */
|
||||
}}
|
||||
a[href*="/404"]::after {{
|
||||
content: " ⚠";
|
||||
}}
|
||||
a[href*="/404"]::before {{
|
||||
content: "⚠ ";
|
||||
}}
|
||||
''')
|
||||
return HttpResponse(stanzas, content_type="text/css")
|
||||
#+end_src
|
||||
=app.html= template would be provided by a configuration-module repo that a user should set up on a template that depends on arroyo, arcology, roam modules. It would be the one responsible for setting up =gunicorn= etc, and also provide the command line wrapper
|
||||
|
||||
* NEXT Testing
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
{# [[file:../../../arcology.org::*Arcology Site Templates][Arcology Site Templates:1]] #}
|
||||
{# [[file:../../../arcology.org::*=app.html= Arcology Site Templates][=app.html= Arcology Site Templates:1]] #}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{# Arcology Site Templates:1 ends here #}
|
||||
{# =app.html= Arcology Site Templates:1 ends here #}
|
||||
|
||||
{# [[file:../../../arcology.org::*Arcology Site Templates][Arcology Site Templates:2]] #}
|
||||
{# [[file:../../../arcology.org::*=app.html= Arcology Site Templates][=app.html= Arcology Site Templates:2]] #}
|
||||
{% load static %}
|
||||
{% load django_htmx %}
|
||||
<link rel="stylesheet" href="{% static 'arcology/css/app.css' %}"/>
|
||||
|
@ -20,9 +20,9 @@
|
|||
<title>{% block title %}{{head_title | default:"The Arcology Project" }}{% endblock %}</title>
|
||||
{% block extra_head %}{% endblock %}
|
||||
</head>
|
||||
{# Arcology Site Templates:2 ends here #}
|
||||
{# =app.html= Arcology Site Templates:2 ends here #}
|
||||
|
||||
{# [[file:../../../arcology.org::*Arcology Site Templates][Arcology Site Templates:3]] #}
|
||||
{# [[file:../../../arcology.org::*=app.html= Arcology Site Templates][=app.html= Arcology Site Templates:3]] #}
|
||||
<body>
|
||||
<header>
|
||||
<div class="header-content">
|
||||
|
@ -39,15 +39,15 @@
|
|||
</div>
|
||||
</div>
|
||||
</header>
|
||||
{# Arcology Site Templates:3 ends here #}
|
||||
{# =app.html= Arcology Site Templates:3 ends here #}
|
||||
|
||||
{# [[file:../../../arcology.org::*Arcology Site Templates][Arcology Site Templates:4]] #}
|
||||
{# [[file:../../../arcology.org::*=app.html= Arcology Site Templates][=app.html= Arcology Site Templates:4]] #}
|
||||
<div class="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
{# Arcology Site Templates:4 ends here #}
|
||||
{# =app.html= Arcology Site Templates:4 ends here #}
|
||||
|
||||
{# [[file:../../../arcology.org::*Arcology Site Templates][Arcology Site Templates:5]] #}
|
||||
{# [[file:../../../arcology.org::*=app.html= Arcology Site Templates][=app.html= Arcology Site Templates:5]] #}
|
||||
<footer>
|
||||
<hr/>
|
||||
© 02024 <a href="https://arcology.garden/people/rrix">Ryan Rix</a> <<a href="mailto:site@whatthefuck.computer">site@whatthefuck.computer</a>>
|
||||
|
@ -82,9 +82,9 @@
|
|||
<a href="https://fediring.net/">Fediring</a>
|
||||
<a href="https://fediring.net/next?host=arcology.garden">→</a>
|
||||
</p>
|
||||
{# Arcology Site Templates:5 ends here #}
|
||||
{# =app.html= Arcology Site Templates:5 ends here #}
|
||||
|
||||
{# [[file:../../../arcology.org::*Arcology Site Templates][Arcology Site Templates:6]] #}
|
||||
{# [[file:../../../arcology.org::*=app.html= Arcology Site Templates][=app.html= Arcology Site Templates:6]] #}
|
||||
<!--
|
||||
<p>
|
||||
<input type="checkbox" id="boredom-mode"><label for="boredom-mode">I do not like your aesthetic sensibilities!!</label>
|
||||
|
@ -97,4 +97,4 @@
|
|||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
{# Arcology Site Templates:6 ends here #}
|
||||
{# =app.html= Arcology Site Templates:6 ends here #}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{# [[file:../../../arcology.org::*=robots.txt= Endpoint][=robots.txt= Endpoint:2]] #}
|
||||
{# [[file:../../../arcology.org::*=GET /robots.txt= Endpoint][=GET /robots.txt= Endpoint:2]] #}
|
||||
{% for agent in disallow_all_agents %}
|
||||
User-agent: {{ agent }}
|
||||
Disallow: /
|
||||
|
@ -8,4 +8,4 @@ User-agent: *
|
|||
Disallow: /
|
||||
{% for page in pages %}Allow: {{ page.to_url_path }}
|
||||
{% endfor %}
|
||||
{# =robots.txt= Endpoint:2 ends here #}
|
||||
{# =GET /robots.txt= Endpoint:2 ends here #}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# [[file:../arcology.org::*The Web Server][The Web Server:2]]
|
||||
import logging
|
||||
from django.http import HttpResponse, HttpResponseNotFound
|
||||
from django.http import HttpResponse, HttpResponseNotFound, Http404
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
|
||||
from arcology.models import Page, Feed, Site
|
||||
|
@ -14,9 +14,7 @@ logger = logging.getLogger(__name__)
|
|||
# [[file:../arcology.org::*=GET /= site index][=GET /= site index:1]]
|
||||
def index(request):
|
||||
site = Site.from_request(request)
|
||||
|
||||
full_key = f"{site.key}/index"
|
||||
|
||||
return render_page(request, site, full_key)
|
||||
# =GET /= site index:1 ends here
|
||||
|
||||
|
@ -94,11 +92,16 @@ def feed(request, key):
|
|||
# Fetch page metadata
|
||||
the_feed = get_object_or_404(Feed, route_key=full_key)
|
||||
entries = the_feed.feedentry_set.order_by("-pubdate").all()[:10]
|
||||
|
||||
if len(entries) == 0:
|
||||
return Http404()
|
||||
|
||||
try:
|
||||
page_author = roam.models.Keyword.objects.get(keyword="AUTHOR", path=the_feed.file).value
|
||||
except roam.models.Keyword.DoesNotExist:
|
||||
logger.warn(f"Feed {key} does not have an AUTHOR!")
|
||||
page_author = "Arcology User"
|
||||
|
||||
page_url = the_feed.file.page_set.first().to_url()
|
||||
updated_at = arrow.get(entries[0].pubdate).format(arrow.FORMAT_RFC3339) # entries is already sorted
|
||||
|
||||
|
@ -135,7 +138,7 @@ def get_item(dictionary, key):
|
|||
return dictionary.get(key)
|
||||
# move this function to somewhere else more reasonable:1 ends here
|
||||
|
||||
# [[file:../arcology.org::*unpublished/not found endpoint][unpublished/not found endpoint:1]]
|
||||
# [[file:../arcology.org::*404 unpublished/not found endpoint][404 unpublished/not found endpoint:1]]
|
||||
def unpublished(request):
|
||||
key = request.GET.get("key")
|
||||
if key is None:
|
||||
|
@ -149,9 +152,9 @@ def unpublished(request):
|
|||
return HttpResponseNotFound(
|
||||
template.render(context, request)
|
||||
)
|
||||
# unpublished/not found endpoint:1 ends here
|
||||
# 404 unpublished/not found endpoint:1 ends here
|
||||
|
||||
# [[file:../arcology.org::*=robots.txt= Endpoint][=robots.txt= Endpoint:1]]
|
||||
# [[file:../arcology.org::*=GET /robots.txt= Endpoint][=GET /robots.txt= Endpoint:1]]
|
||||
def robots(request):
|
||||
site = Site.from_request(request)
|
||||
public_pages = Page.objects \
|
||||
|
@ -165,9 +168,9 @@ def robots(request):
|
|||
disallow_all_agents=["GPTBot", "ChatGPT-User", "Google-Extended", "CCBot", "anthropic-ai"],
|
||||
pages=public_pages,
|
||||
), content_type="text/plain")
|
||||
# =robots.txt= Endpoint:1 ends here
|
||||
# =GET /robots.txt= Endpoint:1 ends here
|
||||
|
||||
# [[file:../arcology.org::*Feed discovery endpoint][Feed discovery endpoint:1]]
|
||||
# [[file:../arcology.org::*=GET /feeds.json= Feed discovery endpoint][=GET /feeds.json= Feed discovery endpoint:1]]
|
||||
import json
|
||||
def feed_list(request):
|
||||
site = Site.from_request(request)
|
||||
|
@ -184,9 +187,9 @@ def feed_list(request):
|
|||
]
|
||||
|
||||
return HttpResponse(json.dumps(ret), content_type="application/json")
|
||||
# Feed discovery endpoint:1 ends here
|
||||
# =GET /feeds.json= Feed discovery endpoint:1 ends here
|
||||
|
||||
# [[file:../arcology.org::*Per-Site link color dynamic CSS endpoint][Per-Site link color dynamic CSS endpoint:1]]
|
||||
# [[file:../arcology.org::*=GET /sites.css= Per-Site link color dynamic CSS endpoint][=GET /sites.css= Per-Site link color dynamic CSS endpoint:1]]
|
||||
def site_css(request):
|
||||
sites = Site.objects.all()
|
||||
stanzas = []
|
||||
|
@ -215,4 +218,4 @@ def site_css(request):
|
|||
}}
|
||||
''')
|
||||
return HttpResponse(stanzas, content_type="text/css")
|
||||
# Per-Site link color dynamic CSS endpoint:1 ends here
|
||||
# =GET /sites.css= Per-Site link color dynamic CSS endpoint:1 ends here
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#+TITLE: Arcology Project Configuration
|
||||
#+filetags: :Project:
|
||||
#+OPTIONS: ^:nil
|
||||
#+ARCOLOGY_KEY: arcology/django/configuration
|
||||
#+ARCOLOGY_KEY: arcology/configuration
|
||||
,#+AUTO_TANGLE: vars:org-babel-default-header-args
|
||||
|
||||
#+ARROYO_NIXOS_MODULE: nixos/arcology2.nix
|
||||
|
|
Loading…
Reference in New Issue