Compare commits

..

1 Commits

Author SHA1 Message Date
2c2c94c2eb Some fixes and updates
- Fix some relationships in the models
- Set up theming system based on user setting
- Use the "/node" endpoint for nodes, rather than "/" which will become
  problematic.
2024-12-06 22:47:11 -06:00
3 changed files with 39 additions and 21 deletions

View File

@ -25,6 +25,8 @@ class NodeType(Model):
slug: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
description: Mapped[str] = mapped_column(Text)
fields: Mapped[list['NodeField']] = relationship(back_populates='node_type')
class NodeRevision(Model):
"""A revision of a content node"""
@ -34,6 +36,7 @@ class NodeRevision(Model):
node_id: Mapped[int] = mapped_column(Integer, ForeignKey('nodes.id'))
revision: Mapped[int] = mapped_column(Integer, default=1)
node: Mapped['Node'] = relationship(back_populates='revisions')
fields: Mapped[list['NodeFieldInstance']] = relationship(secondary=revisions_fields_table,
back_populates='node_revision')
@ -73,7 +76,7 @@ class NodeField(Model):
slug: Mapped[str] = mapped_column(String(255), nullable=False, unique=True, index=True)
field_type: Mapped[str] = mapped_column(String(255))
node_type: Mapped['NodeType'] = relationship(back_populates='node_fields')
node_type: Mapped['NodeType'] = relationship(back_populates='fields')
class NodeFieldInstance(Model):
@ -82,6 +85,8 @@ class NodeFieldInstance(Model):
id: Mapped[int] = mapped_column(Integer, primary_key=True)
node_field_id: Mapped[int] = mapped_column(Integer, ForeignKey('node_fields.id'))
revision_id: Mapped[int] = mapped_column(Integer, ForeignKey('node_revisions.id'))
value: Mapped[str] = mapped_column(Text)
node_field: Mapped['NodeField'] = relationship()
node_revision: Mapped['NodeRevision'] = relationship(back_populates='fields')

View File

@ -1,5 +1,13 @@
from flask_theme import get_theme, render_theme_template, template_exists
from quart import Quart, current_app, request
from flask_theme import get_theme, render_theme_template
from sqlalchemy.query import select
from scribeengine.db.base import Session
from scribeengine.db.models.settings import SettingValue
class TemplateNotExistsError(Exception):
pass
def register_globals(app: Quart) -> None:
@ -13,11 +21,18 @@ def register_globals(app: Quart) -> None:
def get_current_theme():
"""Get the current theme"""
ident = current_app.config.get('DEFAULT_THEME', 'quill')
return get_theme(ident)
default_theme = current_app.config.get('DEFAULT_THEME', 'quill')
with Session as session:
theme_setting = session.scalars(select(SettingValue).where(SettingValue.key.slug == 'theme')).first()
if theme_setting:
return get_theme(theme_setting.get_value())
return get_theme(default_theme)
def render(template, **context):
def render(templates: list[str], **context):
"""Render the template using the current theme"""
theme = get_current_theme()
for template in templates:
if template_exists(template):
return render_theme_template(theme, template, **context)
raise TemplateNotExistsError()

View File

@ -1,13 +1,14 @@
from typing import Union
from quart import Blueprint, render_template, request, abort
from quart import Blueprint, request, abort
from sqlalchemy.sql import select
from scribeengine.db.base import Session
from scribeengine.db.models.node import Node
from scribeengine.util.nodes import get_node, get_node_templates
from scribeengine.templating import render
nodes = Blueprint('nodes', __name__, url_prefix='/')
nodes = Blueprint('nodes', __name__, url_prefix='/node')
def _get_node_list(*filters) -> tuple[int, int, list[Node]]:
@ -24,27 +25,24 @@ def _get_node_list(*filters) -> tuple[int, int, list[Node]]:
@nodes.route('', methods=['GET'])
async def list_nodes():
@nodes.route('/<node_type>', methods=['GET'])
async def list_nodes(node_type: str | None = None):
"""List all the nodes"""
if node_type:
page, page_size, node_list = _get_node_list(Node.node_Type.slug == node_type)
else:
page, page_size, node_list = _get_node_list()
all_nodes = [get_node(node) for node in node_list]
return await render_template('admin/nodes/list_nodes.html', nodes=all_nodes, page=page, page_size=page_size)
node_templates = get_node_templates('node', 'list')
node_templates.insert(0, 'front_page.html')
return await render('nodes/list_nodes.html', nodes=all_nodes, page=page, page_size=page_size)
@nodes.route('/<node_type>', methods=['GET'])
async def list_nodes_by_type(node_type: str):
"""List all the nodes"""
page, page_size, node_list = _get_node_list(Node.node_type.slug == node_type)
all_nodes = [get_node(node) for node in node_list]
node_templates = get_node_templates(node_type, 'list')
return await render_template(node_templates, nodes=all_nodes, page=page, page_size=page_size)
@nodes.route('<slug_or_id>', methods=['GET'])
@nodes.route('/by-slug/<slug_or_id>', methods=['GET'])
async def view_node(slug_or_id: Union[str, int]):
"""View a single node"""
node = get_node(slug_or_id)
if not node:
return await abort(404)
node_templates = get_node_templates(node['node_type'], 'view')
return await render_template(node_templates, node=node)
return await render(node_templates, node=node)