Loading Dockerfile +1 −1 Changes for Dockerfile: 1 added line, 1 removed line. Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ # images from another registry/namespace -- see DOCKER_PREFIX in systempp/build-chroot.sh. ARG IMAGE_PREFIX=tuxist/ ARG FENRIROS_TAG=20261031 ARG FENRIROS_TAG=20261103 FROM ${IMAGE_PREFIX}fenriros-devel:${FENRIROS_TAG} AS build Loading plugins/content/content.cpp +31 −5 Changes for plugins/content/content.cpp: 31 added lines, 5 removed lines. Original line number Diff line number Diff line Loading @@ -2129,6 +2129,10 @@ std::cerr << "DEBUG: authid=" << authid << " currentAuthor=" << currentAuthor << json_object_object_add(f_tags, "placeholder", json_object_new_string(tr(_lang,"tag1 tag2 tag3").c_str())); json_object_array_add(fields, f_tags); // Optional publish date (YYYY-MM-DD from <input type="date">); empty // means today for a new post, or keep the existing date on overwrite. addPublishField(fields, "publish_date", tr(_lang,"Publish date"), "date", ""); // SEO & Social — rendered by the editor into a separate "SEO & Social" dialog. addPublishField(fields, "og_title", tr(_lang,"OG Title (Facebook/LinkedIn)"), "text", "seo", tr(_lang,"Falls back to the post title")); Loading @@ -2150,7 +2154,7 @@ std::cerr << "DEBUG: authid=" << authid << " currentAuthor=" << currentAuthor << std::vector<char> sbuf; json_object *val_obj = nullptr; std::string title, description, tags; std::string title, description, tags, publishDate; std::string ogTitle, ogDescription, ogImage, twitterCard, canonicalUrl, robots; bool robotsNoindex = false, robotsNofollow = false; Loading @@ -2167,6 +2171,10 @@ std::cerr << "DEBUG: authid=" << authid << " currentAuthor=" << currentAuthor << const char *v = json_object_get_string(val_obj); if (v) tags = v; } if (json_object_object_get_ex(params, "publish_date", &val_obj)) { const char *v = json_object_get_string(val_obj); if (v) publishDate = v; } if (json_object_object_get_ex(params, "og_title", &val_obj)) { const char *v = json_object_get_string(val_obj); if (v) ogTitle = v; Loading Loading @@ -2204,14 +2212,30 @@ std::cerr << "DEBUG: authid=" << authid << " currentAuthor=" << currentAuthor << return; } // Only a strict, valid YYYY-MM-DD goes into SQL unescaped below. if (!publishDate.empty()) { int y = 0; unsigned m = 0, d = 0; char tail = 0; bool valid = publishDate.size() == 10 && std::sscanf(publishDate.c_str(), "%4d-%2u-%2u%c", &y, &m, &d, &tail) == 3 && std::chrono::year_month_day{std::chrono::year{y}, std::chrono::month{m}, std::chrono::day{d}}.ok(); if (!valid) { json_object_object_add(response, "status", json_object_new_string("error")); json_object_object_add(response, "message", json_object_new_string(tr(_lang,"Invalid publish date (expected YYYY-MM-DD).").c_str())); return; } } try { std::string time_str; std::string time_str = publishDate; if (time_str.empty()) { auto now = std::chrono::system_clock::now(); try { time_str = std::format("{:%Y-%m-%d}", now); } catch (...) { time_str = "1970-01-01"; } } dbpp::SQL sql; dbpp::DBResult res; Loading Loading @@ -2266,9 +2290,11 @@ std::cerr << "DEBUG: authid=" << authid << " currentAuthor=" << currentAuthor << << "', twitter_card='" << dbpp::SQL::escaped(sbuf, twitterCard.c_str()) << "', canonical_url='" << dbpp::SQL::escaped(sbuf, canonicalUrl.c_str()) << "', robots='" << dbpp::SQL::escaped(sbuf, robots.c_str()) << "', author='" << authorId << "', created='" << time_str.c_str() << "' WHERE id='" << content_id << "';"; << "', author='" << authorId << "'"; // No explicit date on overwrite: keep the original publish date. if (!publishDate.empty()) sql << ", created='" << publishDate.c_str() << "'"; sql << " WHERE id='" << content_id << "';"; Args->database[tid]->exec(sql, res); // Remove old tag links Loading src/translations.h +2 −0 Changes for src/translations.h: 2 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -528,6 +528,8 @@ namespace blogi { {"Post title", "Beitragstitel"}, {"Short description", "Kurzbeschreibung"}, {"Tags", "Schlagworte"}, {"Publish date", "Veröffentlichungsdatum"}, {"Invalid publish date (expected YYYY-MM-DD).", "Ungültiges Veröffentlichungsdatum (erwartet JJJJ-MM-TT)."}, {"tag1 tag2 tag3", "Tag1 Tag2 Tag3"}, {"Title and description are required.", "Titel und Beschreibung sind erforderlich."}, {"No valid author found. Please ensure a user exists.", "Kein gültiger Autor gefunden. Bitte stellen Sie sicher, dass ein Benutzer existiert."}, Loading Loading
Dockerfile +1 −1 Changes for Dockerfile: 1 added line, 1 removed line. Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ # images from another registry/namespace -- see DOCKER_PREFIX in systempp/build-chroot.sh. ARG IMAGE_PREFIX=tuxist/ ARG FENRIROS_TAG=20261031 ARG FENRIROS_TAG=20261103 FROM ${IMAGE_PREFIX}fenriros-devel:${FENRIROS_TAG} AS build Loading
plugins/content/content.cpp +31 −5 Changes for plugins/content/content.cpp: 31 added lines, 5 removed lines. Original line number Diff line number Diff line Loading @@ -2129,6 +2129,10 @@ std::cerr << "DEBUG: authid=" << authid << " currentAuthor=" << currentAuthor << json_object_object_add(f_tags, "placeholder", json_object_new_string(tr(_lang,"tag1 tag2 tag3").c_str())); json_object_array_add(fields, f_tags); // Optional publish date (YYYY-MM-DD from <input type="date">); empty // means today for a new post, or keep the existing date on overwrite. addPublishField(fields, "publish_date", tr(_lang,"Publish date"), "date", ""); // SEO & Social — rendered by the editor into a separate "SEO & Social" dialog. addPublishField(fields, "og_title", tr(_lang,"OG Title (Facebook/LinkedIn)"), "text", "seo", tr(_lang,"Falls back to the post title")); Loading @@ -2150,7 +2154,7 @@ std::cerr << "DEBUG: authid=" << authid << " currentAuthor=" << currentAuthor << std::vector<char> sbuf; json_object *val_obj = nullptr; std::string title, description, tags; std::string title, description, tags, publishDate; std::string ogTitle, ogDescription, ogImage, twitterCard, canonicalUrl, robots; bool robotsNoindex = false, robotsNofollow = false; Loading @@ -2167,6 +2171,10 @@ std::cerr << "DEBUG: authid=" << authid << " currentAuthor=" << currentAuthor << const char *v = json_object_get_string(val_obj); if (v) tags = v; } if (json_object_object_get_ex(params, "publish_date", &val_obj)) { const char *v = json_object_get_string(val_obj); if (v) publishDate = v; } if (json_object_object_get_ex(params, "og_title", &val_obj)) { const char *v = json_object_get_string(val_obj); if (v) ogTitle = v; Loading Loading @@ -2204,14 +2212,30 @@ std::cerr << "DEBUG: authid=" << authid << " currentAuthor=" << currentAuthor << return; } // Only a strict, valid YYYY-MM-DD goes into SQL unescaped below. if (!publishDate.empty()) { int y = 0; unsigned m = 0, d = 0; char tail = 0; bool valid = publishDate.size() == 10 && std::sscanf(publishDate.c_str(), "%4d-%2u-%2u%c", &y, &m, &d, &tail) == 3 && std::chrono::year_month_day{std::chrono::year{y}, std::chrono::month{m}, std::chrono::day{d}}.ok(); if (!valid) { json_object_object_add(response, "status", json_object_new_string("error")); json_object_object_add(response, "message", json_object_new_string(tr(_lang,"Invalid publish date (expected YYYY-MM-DD).").c_str())); return; } } try { std::string time_str; std::string time_str = publishDate; if (time_str.empty()) { auto now = std::chrono::system_clock::now(); try { time_str = std::format("{:%Y-%m-%d}", now); } catch (...) { time_str = "1970-01-01"; } } dbpp::SQL sql; dbpp::DBResult res; Loading Loading @@ -2266,9 +2290,11 @@ std::cerr << "DEBUG: authid=" << authid << " currentAuthor=" << currentAuthor << << "', twitter_card='" << dbpp::SQL::escaped(sbuf, twitterCard.c_str()) << "', canonical_url='" << dbpp::SQL::escaped(sbuf, canonicalUrl.c_str()) << "', robots='" << dbpp::SQL::escaped(sbuf, robots.c_str()) << "', author='" << authorId << "', created='" << time_str.c_str() << "' WHERE id='" << content_id << "';"; << "', author='" << authorId << "'"; // No explicit date on overwrite: keep the original publish date. if (!publishDate.empty()) sql << ", created='" << publishDate.c_str() << "'"; sql << " WHERE id='" << content_id << "';"; Args->database[tid]->exec(sql, res); // Remove old tag links Loading
src/translations.h +2 −0 Changes for src/translations.h: 2 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -528,6 +528,8 @@ namespace blogi { {"Post title", "Beitragstitel"}, {"Short description", "Kurzbeschreibung"}, {"Tags", "Schlagworte"}, {"Publish date", "Veröffentlichungsdatum"}, {"Invalid publish date (expected YYYY-MM-DD).", "Ungültiges Veröffentlichungsdatum (erwartet JJJJ-MM-TT)."}, {"tag1 tag2 tag3", "Tag1 Tag2 Tag3"}, {"Title and description are required.", "Titel und Beschreibung sind erforderlich."}, {"No valid author found. Please ensure a user exists.", "Kein gültiger Autor gefunden. Bitte stellen Sie sicher, dass ein Benutzer existiert."}, Loading