Migrate to crafter-build project.cpp and restructure views
- Replace project.json + run.sh with a C++ project.cpp build descriptor (crafter-build), targeting wasm32-wasip1 with the Crafter.Graphics dep - Add Catcrafts-Views implementation; drop Catcrafts-Component - Add catcrafts-head.js (sets <title>/<link> tags at runtime) - Update Blog/Root/main modules, README, and favicon Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d87c408712
commit
13a12c2a2c
15 changed files with 227 additions and 126 deletions
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
catcrafts.net
|
||||
Copyright (C) 2025 Catcrafts
|
||||
Copyright (C) 2026 Catcrafts
|
||||
|
||||
The source code of this website is made available for viewing purposes only.
|
||||
The source code of this website is made available for viewing purposes only.
|
||||
No permission is granted to copy, modify, distribute, or create derivative works.
|
||||
*/
|
||||
|
||||
|
|
@ -10,22 +10,24 @@ export module Catcrafts:Blog_impl;
|
|||
import :Blog;
|
||||
import :Root;
|
||||
import :Views;
|
||||
import Crafter.Graphics;
|
||||
import std;
|
||||
|
||||
using namespace Crafter::CppDOMBindings;
|
||||
using namespace Crafter;
|
||||
|
||||
export namespace Catcrafts {
|
||||
std::vector<HtmlElementView> blogButtons;
|
||||
// Persistent storage for the per-post card click handlers. HtmlElementPtr
|
||||
// unregisters its listeners on destruction, so the elements have to
|
||||
// outlive Render(); clear() at the top of RenderBlog() detaches the
|
||||
// previous render's handlers before we attach the new ones.
|
||||
std::vector<Dom::HtmlElementPtr> blogButtons;
|
||||
|
||||
void RenderBlog() {
|
||||
blogButtons.clear();
|
||||
std::string html = "";
|
||||
for(const BlogPost& post : posts) {
|
||||
std::cout << "test" << std::endl;
|
||||
// For preview, we'll limit the content to first 200 characters
|
||||
std::string previewContent = post.content;
|
||||
if(previewContent.length() > 200) {
|
||||
// Find the last space before 200 characters to avoid cutting words
|
||||
std::size_t lastSpace = previewContent.find_last_of(' ', 200);
|
||||
if(lastSpace != std::string::npos) {
|
||||
previewContent = previewContent.substr(0, lastSpace) + "...";
|
||||
|
|
@ -47,24 +49,21 @@ export namespace Catcrafts {
|
|||
</div>
|
||||
</div>)", post.slug, post.name, post.date, previewContent);
|
||||
}
|
||||
main.SetInnerHTML(std::format(R"(<div class="blog-posts">{}</div>)", html));
|
||||
MainContent().SetInnerHTML(std::format(R"(<div class="blog-posts">{}</div>)", html));
|
||||
|
||||
for(const BlogPost& post : posts) {
|
||||
// Add click listener to the entire post card
|
||||
HtmlElementView& cardView = blogButtons.emplace_back(std::format("blog-post-{}", post.slug));
|
||||
cardView.AddClickListener([slug = post.slug](Crafter::MouseEvent e) {
|
||||
PushState("{}", "", std::format("/blog/{}", slug));
|
||||
Dom::HtmlElementPtr& cardView = blogButtons.emplace_back(std::format("blog-post-{}", post.slug));
|
||||
cardView.AddClickListener([slug = post.slug](Dom::MouseEvent) {
|
||||
Router::PushState("{}", "", std::format("/blog/{}", slug));
|
||||
RenderRoot(std::format("/blog/{}", slug));
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RenderBlogPost(const std::string_view slug) {
|
||||
std::cout << "render "<< std::endl;
|
||||
for(const BlogPost& post : posts) {
|
||||
if(post.slug == slug) {
|
||||
main.SetInnerHTML(std::format(R"(
|
||||
MainContent().SetInnerHTML(std::format(R"(
|
||||
<div class="blog-post-page">
|
||||
<div class="post-header">
|
||||
<h1 class="post-title">{}</h1>
|
||||
|
|
@ -78,6 +77,6 @@ export namespace Catcrafts {
|
|||
}
|
||||
}
|
||||
|
||||
main.SetInnerHTML("<h1>Post Not Found</h1><p>The requested blog post could not be found.</p>");
|
||||
MainContent().SetInnerHTML("<h1>Post Not Found</h1><p>The requested blog post could not be found.</p>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue