using Astralis; using Inversion; using Invercargill; using Invercargill.DataStructures; namespace Spry { public abstract class PageComponent : Component, Endpoint { private Scope scope = inject(); public abstract string title { get; } public async Astralis.HttpResult handle_request (HttpContext http_context, RouteContext route_context) throws Error { // Register a context for anything that gets instansiated after this scope.register_local_scoped(() => new PageContext(this)); // Get templates as renderables in order of lowest to highest "rank" var renderables = scope.get_registrations(typeof(PageTemplate)) .select_many>(r => r.get_metadata().select_pairs(p => r, p => p)) .where(p => p.value2.matches_route(route_context)) .order_by(p => p.value2.rank) .attempt_select(p => scope.resolve_registration (p.value1)) .cast() .to_series(); // Finally, add this page renderables.add(this); MarkupDocument result = null; foreach (var renderable in renderables) { var document = yield renderable.to_document(); if(result == null){ result = document; continue; } var content_added = false; foreach(var outlet in result.select("//spry-content")) { outlet.replace_with_nodes(document.body.children); content_added = true; } if(content_added && document.head != null) { result.head.append_nodes(document.head.children); } } return result.to_result(get_status()); } } public class PageContext : Object { public PageComponent component { get; private set; } public Type page_type { get { return component.get_type(); }} public string title { get { return component.title; }} public PageContext(PageComponent component) { this.component = component; } } }