Loading editor/widgets/accordion/accordion.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "plugin.h" #include "translations.h" #include "llms_text.h" #include "../common/css_id.h" extern "C" { namespace blogi::webedit { Loading Loading @@ -96,6 +97,9 @@ extern "C" { bool hidden = false; bool m_hidden = false; // Custom CSS ID std::string cssId = ""; // Custom CSS std::string customCss = ""; Loading Loading @@ -258,6 +262,9 @@ extern "C" { addField("open_by_default", "Open by Default", "checkbox", nullptr, "all", nullptr, nullptr, "simple"); addField("icon_position", "Toggle Icon Position", "select", nullptr, "all", mkOpts({"right", "left", "none"}), nullptr, "simple"); // Custom CSS ID addField("css_id", "CSS ID", "text", "e.g. my-accordion"); // Visibility addField("hidden", "Hidden", "checkbox", nullptr, "desktop", nullptr, nullptr, "simple"); { Loading Loading @@ -332,6 +339,8 @@ extern "C" { element->SetAttribute("open_by_default", openByDefault ? "true" : "false"); element->SetAttribute("icon_position", iconPosition.c_str()); element->SetAttribute("css_id", cssId.c_str()); element->SetAttribute("hidden", hidden ? "true" : "false"); element->SetAttribute("m_hidden", m_hidden ? "true" : "false"); Loading Loading @@ -400,6 +409,9 @@ extern "C" { val = xml_data->Attribute("icon_position"); if (val) iconPosition = val; val = xml_data->Attribute("css_id"); if (val) cssId = val; val = xml_data->Attribute("hidden"); if (val) hidden = (strcmp(val, "true") == 0); val = xml_data->Attribute("m_hidden"); Loading Loading @@ -466,6 +478,8 @@ extern "C" { json_object_object_add(obj, "open_by_default", json_object_new_boolean(openByDefault)); json_object_object_add(obj, "icon_position", json_object_new_string(iconPosition.c_str())); json_object_object_add(obj, "css_id", json_object_new_string(cssId.c_str())); json_object_object_add(obj, "hidden", json_object_new_boolean(hidden)); json_object_object_add(obj, "m_hidden", json_object_new_boolean(m_hidden)); json_object_object_add(obj, "custom_css", json_object_new_string(customCss.c_str())); Loading Loading @@ -592,6 +606,9 @@ extern "C" { if (json_object_object_get_ex(obj, "icon_position", &val_obj)) { val = json_object_get_string(val_obj); if (val && val[0]) iconPosition = val; } if (json_object_object_get_ex(obj, "css_id", &val_obj)) { val = json_object_get_string(val_obj); if (val) cssId = val; } if (json_object_object_get_ex(obj, "hidden", &val_obj)) { if (json_object_is_type(val_obj, json_type_string)) { const char *s = json_object_get_string(val_obj); Loading Loading @@ -653,6 +670,8 @@ extern "C" { // --- Wrapper --- libhtmlpp::HtmlElement wrapper("div"); wrapper.setAttribute("class", (rc + "-acc").c_str()); std::string customCssId = sanitizeCssId(cssId); wrapper.setAttribute("id", (customCssId.empty() ? rc : customCssId).c_str()); std::string wrapperStyle; if (validCss(borderColor)) wrapperStyle += "border: 1px solid " + borderColor + ";"; Loading Loading @@ -835,6 +854,8 @@ extern "C" { } } std::string getCssId() const override { return sanitizeCssId(cssId); } // --- Element Management (Accordion is a container) --- bool canHaveChildren() const override { return true; } bool haveChilds() override { return child != nullptr; } Loading editor/widgets/article/article.cpp +15 −1 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "plugin.h" #include "translations.h" #include "llms_text.h" #include "../common/css_id.h" extern "C" { namespace blogi::webedit { Loading @@ -44,6 +45,7 @@ extern "C" { std::string content; std::string backgroundColor = ""; std::string cssClass = ""; std::string cssId = ""; std::string borderRadius = ""; std::string borderStyle = ""; std::string opacity = ""; Loading Loading @@ -233,6 +235,7 @@ extern "C" { addField("m_background_gradient_angle", "Mobile Gradient Angle", "text", "e.g. 135deg", "mobile"); addField("m_background_gradient_custom", "Mobile Gradient Custom", "text", "e.g. linear-gradient(135deg, #ff0000, #0000ff)", "mobile"); addField("css_class", "CSS Class", "text", "e.g. card"); addField("css_id", "CSS ID", "text", "e.g. my-article"); addSpacingBox("padding", "Padding", "desktop"); addSpacingBox("margin", "Margin", "desktop"); addField("max_width", "Max Width", "text", "e.g. 800px", "desktop"); Loading Loading @@ -278,6 +281,7 @@ extern "C" { element->SetAttribute("background_color", backgroundColor.c_str()); element->SetAttribute("css_class", cssClass.c_str()); element->SetAttribute("css_id", cssId.c_str()); element->SetAttribute("border_radius", borderRadius.c_str()); element->SetAttribute("border_style", borderStyle.c_str()); element->SetAttribute("opacity", opacity.c_str()); Loading Loading @@ -361,6 +365,8 @@ extern "C" { if (val) backgroundColor = val; val = xml_data->Attribute("css_class"); if (val) cssClass = val; val = xml_data->Attribute("css_id"); if (val) cssId = val; val = xml_data->Attribute("border_radius"); if (val) borderRadius = val; val = xml_data->Attribute("border_style"); Loading Loading @@ -484,6 +490,7 @@ extern "C" { json_object *obj = json_object_new_object(); json_object_object_add(obj, "background_color", json_object_new_string(backgroundColor.c_str())); json_object_object_add(obj, "css_class", json_object_new_string(cssClass.c_str())); json_object_object_add(obj, "css_id", json_object_new_string(cssId.c_str())); json_object_object_add(obj, "border_radius", json_object_new_string(borderRadius.c_str())); json_object_object_add(obj, "border_style", json_object_new_string(borderStyle.c_str())); json_object_object_add(obj, "opacity", json_object_new_string(opacity.c_str())); Loading Loading @@ -548,6 +555,10 @@ extern "C" { val = json_object_get_string(val_obj); if (val) cssClass = val; } if (json_object_object_get_ex(obj, "css_id", &val_obj)) { val = json_object_get_string(val_obj); if (val) cssId = val; } if (json_object_object_get_ex(obj, "border_radius", &val_obj)) { val = json_object_get_string(val_obj); if (val) borderRadius = val; Loading Loading @@ -739,7 +750,8 @@ extern "C" { std::string responsiveClass = std::string("we-") + getInstanceId().c_str(); art.setAttribute("id", responsiveClass.c_str()); std::string customCssId = sanitizeCssId(cssId); art.setAttribute("id", (customCssId.empty() ? responsiveClass : customCssId).c_str()); auto gradientCss = [](const std::string &type, const std::string &angle, const std::string &c1, const std::string &c2) -> std::string { if (type == "linear") { Loading Loading @@ -895,6 +907,8 @@ extern "C" { bool haveChilds() override { return child != nullptr; } std::string getCssId() const override { return sanitizeCssId(cssId); } void setChildElement(const EditPlugin &el) override { child = const_cast<EditPlugin*>(&el); } Loading editor/widgets/container/container.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "plugin.h" #include "translations.h" #include "../common/css_id.h" extern "C" { namespace blogi::webedit { Loading @@ -43,6 +44,7 @@ extern "C" { std::string content; std::string backgroundColor = ""; std::string cssClass = ""; std::string cssId = ""; std::string borderRadius = ""; std::string borderStyle = ""; std::string opacity = ""; Loading Loading @@ -349,6 +351,7 @@ extern "C" { addField("width", "Width", "text", "e.g. 100%", "desktop"); addField("height", "Height", "text", "e.g. auto", "desktop"); addField("css_class", "CSS Class", "text", "e.g. my-container"); addField("css_id", "CSS ID", "text", "e.g. my-container"); addField("border_radius", "Border Radius", "text", "e.g. 8px", "desktop"); addField("border_style", "Border", "text", "e.g. 1px solid #ccc", "desktop"); addField("opacity", "Opacity", "text", "0.0 - 1.0", "desktop"); Loading Loading @@ -437,6 +440,7 @@ extern "C" { // Persist properties element->SetAttribute("background_color", backgroundColor.c_str()); element->SetAttribute("css_class", cssClass.c_str()); element->SetAttribute("css_id", cssId.c_str()); element->SetAttribute("border_radius", borderRadius.c_str()); element->SetAttribute("border_style", borderStyle.c_str()); element->SetAttribute("opacity", opacity.c_str()); Loading Loading @@ -556,6 +560,9 @@ extern "C" { const char* loaded_class = xml_data->Attribute("css_class"); if (loaded_class) cssClass = loaded_class; const char* loaded_id = xml_data->Attribute("css_id"); if (loaded_id) cssId = loaded_id; const char* loaded_br = xml_data->Attribute("border_radius"); if (loaded_br) borderRadius = loaded_br; Loading Loading @@ -743,6 +750,7 @@ extern "C" { json_object *obj = json_object_new_object(); json_object_object_add(obj, "background_color", json_object_new_string(backgroundColor.c_str())); json_object_object_add(obj, "css_class", json_object_new_string(cssClass.c_str())); json_object_object_add(obj, "css_id", json_object_new_string(cssId.c_str())); json_object_object_add(obj, "border_radius", json_object_new_string(borderRadius.c_str())); json_object_object_add(obj, "border_style", json_object_new_string(borderStyle.c_str())); json_object_object_add(obj, "opacity", json_object_new_string(opacity.c_str())); Loading Loading @@ -829,6 +837,10 @@ extern "C" { val = json_object_get_string(val_obj); if (val) cssClass = val; } if (json_object_object_get_ex(obj, "css_id", &val_obj)) { val = json_object_get_string(val_obj); if (val) cssId = val; } if (json_object_object_get_ex(obj, "border_radius", &val_obj)) { val = json_object_get_string(val_obj); if (val) borderRadius = val; Loading Loading @@ -1219,6 +1231,8 @@ extern "C" { cls = cssClass + " " + responsiveClass; } cnt.setAttribute("class", cls.c_str()); std::string customCssId = sanitizeCssId(cssId); cnt.setAttribute("id", (customCssId.empty() ? responsiveClass : customCssId).c_str()); if (!dataAttrs.empty()) applyDataAttrs(cnt, dataAttrs); // Shape divider: a decorative wave/oval SVG pinned to the Loading Loading @@ -1433,6 +1447,8 @@ extern "C" { bool haveChilds() override { return child != nullptr; } std::string getCssId() const override { return sanitizeCssId(cssId); } /** * @brief Sets the first child element of this container. * @param el The EditPlugin element to be set as the first child. Loading editor/widgets/faq/faq.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "plugin.h" #include "translations.h" #include "llms_text.h" #include "../common/css_id.h" extern "C" { namespace blogi::webedit { Loading @@ -53,6 +54,7 @@ extern "C" { // Container styling std::string title = ""; std::string cssId = ""; std::string titleFontSize = "24px"; std::string titleColor = "var(--blogi-text)"; std::string paddingTop = "0"; Loading Loading @@ -246,6 +248,7 @@ extern "C" { addField("title_font_size", "Title Font Size", "text", "24px", "desktop"); addField("title_color", "Title Color (Dark)", "color_var", nullptr, "all", nullptr, "simple"); addField("l_title_color", "Title Color (Light)", "color_var", nullptr, "light", nullptr, "simple"); addField("css_id", "CSS ID", "text", "e.g. my-faq"); addSpacingBox("padding", "Padding", "desktop"); addField("max_width", "Max Width", "text", "e.g. 800px"); addField("columns", "Spalten", "select", nullptr, "desktop", mkOpts({"1","2","3","4"}), "simple"); Loading Loading @@ -336,6 +339,7 @@ extern "C" { element->SetAttribute("type_id", getTypeId().c_str()); element->SetAttribute("title", title.c_str()); element->SetAttribute("css_id", cssId.c_str()); element->SetAttribute("title_font_size", titleFontSize.c_str()); element->SetAttribute("title_color", titleColor.c_str()); element->SetAttribute("padding_top", paddingTop.c_str()); Loading Loading @@ -399,6 +403,7 @@ extern "C" { const char *val = nullptr; val = xml_data->Attribute("title"); if (val) title = val; val = xml_data->Attribute("css_id"); if (val) cssId = val; val = xml_data->Attribute("title_font_size"); if (val) titleFontSize = val; val = xml_data->Attribute("title_color"); if (val) titleColor = val; // Legacy migration: pre-split documents stored padding as a Loading Loading @@ -493,6 +498,7 @@ extern "C" { json_object *obj = json_object_new_object(); json_object_object_add(obj, "title", json_object_new_string(title.c_str())); json_object_object_add(obj, "css_id", json_object_new_string(cssId.c_str())); json_object_object_add(obj, "title_font_size", json_object_new_string(titleFontSize.c_str())); json_object_object_add(obj, "title_color", json_object_new_string(titleColor.c_str())); json_object_object_add(obj, "padding_top", json_object_new_string(paddingTop.c_str())); Loading Loading @@ -583,6 +589,7 @@ extern "C" { }; strNonEmpty("title", title); str("css_id", cssId); strNonEmpty("title_font_size", titleFontSize); strNonEmpty("title_color", titleColor); str("padding_top", paddingTop); Loading Loading @@ -685,6 +692,8 @@ extern "C" { // Outer container libhtmlpp::HtmlElement outer("div"); outer.setAttribute("class", (rc + "-faq").c_str()); std::string customCssId = sanitizeCssId(cssId); outer.setAttribute("id", (customCssId.empty() ? rc : customCssId).c_str()); outer.setAttribute("itemscope", ""); outer.setAttribute("itemtype", "https://schema.org/FAQPage"); Loading Loading @@ -907,6 +916,8 @@ extern "C" { bool canHaveChildren() const override { return false; } bool haveChilds() override { return false; } std::string getCssId() const override { return sanitizeCssId(cssId); } void setChildElement(const EditPlugin &) override {} void unsetChildElement(const EditPlugin &) override {} void addNextElement(const EditPlugin &) override {} Loading editor/widgets/googlereviews/googlereviews.cpp +61 −4 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ #include <json-c/json.h> #include <plugin.h> #include "../common/css_id.h" namespace blogi { namespace webedit { Loading @@ -21,6 +22,11 @@ namespace blogi { void logError(const std::string& message) override {} private: std::string cssId = ""; public: void JsonApi(json_object *request, json_object *response) override { json_object *action_obj = nullptr; const char *action = nullptr; Loading @@ -29,13 +35,18 @@ namespace blogi { } if (!action) return; if (strcmp(action, "read") == 0) { if (strcmp(action, "modify_bulk") == 0) { json_object *props_obj = nullptr; if (json_object_object_get_ex(request, "properties", &props_obj)) { const char *s = json_object_to_json_string_ext(props_obj, JSON_C_TO_STRING_NOSLASHESCAPE); if (s) fromPropertiesJson(s); } } else if (strcmp(action, "read") == 0) { json_object *result_obj = json_object_new_object(); json_object_object_add(result_obj, "properties", json_object_new_string("{}")); json_object_object_add(result_obj, "properties", json_object_new_string(toPropertiesJson().c_str())); if (response) json_object_object_add(response, "data", result_obj); } else if (strcmp(action, "get_schema") == 0) { json_object *arr = json_object_new_array(); if (response) json_object_object_add(response, "schema", arr); if (response) json_object_object_add(response, "schema", getSchemaJson()); } if (response != nullptr) { Loading @@ -44,9 +55,48 @@ namespace blogi { } } json_object* getSchemaJson() { json_object *arr = json_object_new_array(); auto addField = [&](const char *key, const char *label, const char *type, const char *placeholder = nullptr, const char *target = "all", const char *level = "expert") { json_object *f = json_object_new_object(); json_object_object_add(f, "key", json_object_new_string(key)); json_object_object_add(f, "label", json_object_new_string(label)); json_object_object_add(f, "type", json_object_new_string(type)); if (placeholder) json_object_object_add(f, "placeholder", json_object_new_string(placeholder)); json_object_object_add(f, "target", json_object_new_string(target)); json_object_object_add(f, "level", json_object_new_string(level)); json_object_array_add(arr, f); }; addField("css_id", "CSS ID", "text", "e.g. my-reviews"); return arr; } std::string toPropertiesJson() { json_object *obj = json_object_new_object(); json_object_object_add(obj, "css_id", json_object_new_string(cssId.c_str())); std::string s = json_object_to_json_string_ext(obj, JSON_C_TO_STRING_NOSLASHESCAPE); json_object_put(obj); return s; } void fromPropertiesJson(const std::string &json) { json_object *obj = json_tokener_parse(json.c_str()); if (!obj) return; json_object *val_obj = nullptr; const char *val = nullptr; if (json_object_object_get_ex(obj, "css_id", &val_obj)) { val = json_object_get_string(val_obj); if (val) cssId = val; } json_object_put(obj); } tinyxml2::XMLElement* toXmlObject(tinyxml2::XMLDocument* doc) override { tinyxml2::XMLElement* el = doc->NewElement("GoogleReviews"); el->SetAttribute("id", Id.c_str()); el->SetAttribute("css_id", cssId.c_str()); return el; } Loading @@ -55,7 +105,12 @@ namespace blogi { uuid::uuid newId; if(newId.parse(id_attr)) Id = newId; } if (const char *css_id_attr = xml_data->Attribute("css_id")) { cssId = css_id_attr; } } std::string getCssId() const override { return sanitizeCssId(cssId); } bool canHaveChildren() const override { return false; } Loading @@ -65,6 +120,8 @@ namespace blogi { void Render(libhtmlpp::HtmlElement &el) const override { std::string uid = "gr_" + std::string(Id.c_str()); std::string customCssId = sanitizeCssId(cssId); if (!customCssId.empty()) uid = customCssId; std::string responsiveClass = std::string("we-") + getInstanceId().c_str(); libhtmlpp::HtmlElement *container = new libhtmlpp::HtmlElement("div"); Loading Loading
editor/widgets/accordion/accordion.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "plugin.h" #include "translations.h" #include "llms_text.h" #include "../common/css_id.h" extern "C" { namespace blogi::webedit { Loading Loading @@ -96,6 +97,9 @@ extern "C" { bool hidden = false; bool m_hidden = false; // Custom CSS ID std::string cssId = ""; // Custom CSS std::string customCss = ""; Loading Loading @@ -258,6 +262,9 @@ extern "C" { addField("open_by_default", "Open by Default", "checkbox", nullptr, "all", nullptr, nullptr, "simple"); addField("icon_position", "Toggle Icon Position", "select", nullptr, "all", mkOpts({"right", "left", "none"}), nullptr, "simple"); // Custom CSS ID addField("css_id", "CSS ID", "text", "e.g. my-accordion"); // Visibility addField("hidden", "Hidden", "checkbox", nullptr, "desktop", nullptr, nullptr, "simple"); { Loading Loading @@ -332,6 +339,8 @@ extern "C" { element->SetAttribute("open_by_default", openByDefault ? "true" : "false"); element->SetAttribute("icon_position", iconPosition.c_str()); element->SetAttribute("css_id", cssId.c_str()); element->SetAttribute("hidden", hidden ? "true" : "false"); element->SetAttribute("m_hidden", m_hidden ? "true" : "false"); Loading Loading @@ -400,6 +409,9 @@ extern "C" { val = xml_data->Attribute("icon_position"); if (val) iconPosition = val; val = xml_data->Attribute("css_id"); if (val) cssId = val; val = xml_data->Attribute("hidden"); if (val) hidden = (strcmp(val, "true") == 0); val = xml_data->Attribute("m_hidden"); Loading Loading @@ -466,6 +478,8 @@ extern "C" { json_object_object_add(obj, "open_by_default", json_object_new_boolean(openByDefault)); json_object_object_add(obj, "icon_position", json_object_new_string(iconPosition.c_str())); json_object_object_add(obj, "css_id", json_object_new_string(cssId.c_str())); json_object_object_add(obj, "hidden", json_object_new_boolean(hidden)); json_object_object_add(obj, "m_hidden", json_object_new_boolean(m_hidden)); json_object_object_add(obj, "custom_css", json_object_new_string(customCss.c_str())); Loading Loading @@ -592,6 +606,9 @@ extern "C" { if (json_object_object_get_ex(obj, "icon_position", &val_obj)) { val = json_object_get_string(val_obj); if (val && val[0]) iconPosition = val; } if (json_object_object_get_ex(obj, "css_id", &val_obj)) { val = json_object_get_string(val_obj); if (val) cssId = val; } if (json_object_object_get_ex(obj, "hidden", &val_obj)) { if (json_object_is_type(val_obj, json_type_string)) { const char *s = json_object_get_string(val_obj); Loading Loading @@ -653,6 +670,8 @@ extern "C" { // --- Wrapper --- libhtmlpp::HtmlElement wrapper("div"); wrapper.setAttribute("class", (rc + "-acc").c_str()); std::string customCssId = sanitizeCssId(cssId); wrapper.setAttribute("id", (customCssId.empty() ? rc : customCssId).c_str()); std::string wrapperStyle; if (validCss(borderColor)) wrapperStyle += "border: 1px solid " + borderColor + ";"; Loading Loading @@ -835,6 +854,8 @@ extern "C" { } } std::string getCssId() const override { return sanitizeCssId(cssId); } // --- Element Management (Accordion is a container) --- bool canHaveChildren() const override { return true; } bool haveChilds() override { return child != nullptr; } Loading
editor/widgets/article/article.cpp +15 −1 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "plugin.h" #include "translations.h" #include "llms_text.h" #include "../common/css_id.h" extern "C" { namespace blogi::webedit { Loading @@ -44,6 +45,7 @@ extern "C" { std::string content; std::string backgroundColor = ""; std::string cssClass = ""; std::string cssId = ""; std::string borderRadius = ""; std::string borderStyle = ""; std::string opacity = ""; Loading Loading @@ -233,6 +235,7 @@ extern "C" { addField("m_background_gradient_angle", "Mobile Gradient Angle", "text", "e.g. 135deg", "mobile"); addField("m_background_gradient_custom", "Mobile Gradient Custom", "text", "e.g. linear-gradient(135deg, #ff0000, #0000ff)", "mobile"); addField("css_class", "CSS Class", "text", "e.g. card"); addField("css_id", "CSS ID", "text", "e.g. my-article"); addSpacingBox("padding", "Padding", "desktop"); addSpacingBox("margin", "Margin", "desktop"); addField("max_width", "Max Width", "text", "e.g. 800px", "desktop"); Loading Loading @@ -278,6 +281,7 @@ extern "C" { element->SetAttribute("background_color", backgroundColor.c_str()); element->SetAttribute("css_class", cssClass.c_str()); element->SetAttribute("css_id", cssId.c_str()); element->SetAttribute("border_radius", borderRadius.c_str()); element->SetAttribute("border_style", borderStyle.c_str()); element->SetAttribute("opacity", opacity.c_str()); Loading Loading @@ -361,6 +365,8 @@ extern "C" { if (val) backgroundColor = val; val = xml_data->Attribute("css_class"); if (val) cssClass = val; val = xml_data->Attribute("css_id"); if (val) cssId = val; val = xml_data->Attribute("border_radius"); if (val) borderRadius = val; val = xml_data->Attribute("border_style"); Loading Loading @@ -484,6 +490,7 @@ extern "C" { json_object *obj = json_object_new_object(); json_object_object_add(obj, "background_color", json_object_new_string(backgroundColor.c_str())); json_object_object_add(obj, "css_class", json_object_new_string(cssClass.c_str())); json_object_object_add(obj, "css_id", json_object_new_string(cssId.c_str())); json_object_object_add(obj, "border_radius", json_object_new_string(borderRadius.c_str())); json_object_object_add(obj, "border_style", json_object_new_string(borderStyle.c_str())); json_object_object_add(obj, "opacity", json_object_new_string(opacity.c_str())); Loading Loading @@ -548,6 +555,10 @@ extern "C" { val = json_object_get_string(val_obj); if (val) cssClass = val; } if (json_object_object_get_ex(obj, "css_id", &val_obj)) { val = json_object_get_string(val_obj); if (val) cssId = val; } if (json_object_object_get_ex(obj, "border_radius", &val_obj)) { val = json_object_get_string(val_obj); if (val) borderRadius = val; Loading Loading @@ -739,7 +750,8 @@ extern "C" { std::string responsiveClass = std::string("we-") + getInstanceId().c_str(); art.setAttribute("id", responsiveClass.c_str()); std::string customCssId = sanitizeCssId(cssId); art.setAttribute("id", (customCssId.empty() ? responsiveClass : customCssId).c_str()); auto gradientCss = [](const std::string &type, const std::string &angle, const std::string &c1, const std::string &c2) -> std::string { if (type == "linear") { Loading Loading @@ -895,6 +907,8 @@ extern "C" { bool haveChilds() override { return child != nullptr; } std::string getCssId() const override { return sanitizeCssId(cssId); } void setChildElement(const EditPlugin &el) override { child = const_cast<EditPlugin*>(&el); } Loading
editor/widgets/container/container.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "plugin.h" #include "translations.h" #include "../common/css_id.h" extern "C" { namespace blogi::webedit { Loading @@ -43,6 +44,7 @@ extern "C" { std::string content; std::string backgroundColor = ""; std::string cssClass = ""; std::string cssId = ""; std::string borderRadius = ""; std::string borderStyle = ""; std::string opacity = ""; Loading Loading @@ -349,6 +351,7 @@ extern "C" { addField("width", "Width", "text", "e.g. 100%", "desktop"); addField("height", "Height", "text", "e.g. auto", "desktop"); addField("css_class", "CSS Class", "text", "e.g. my-container"); addField("css_id", "CSS ID", "text", "e.g. my-container"); addField("border_radius", "Border Radius", "text", "e.g. 8px", "desktop"); addField("border_style", "Border", "text", "e.g. 1px solid #ccc", "desktop"); addField("opacity", "Opacity", "text", "0.0 - 1.0", "desktop"); Loading Loading @@ -437,6 +440,7 @@ extern "C" { // Persist properties element->SetAttribute("background_color", backgroundColor.c_str()); element->SetAttribute("css_class", cssClass.c_str()); element->SetAttribute("css_id", cssId.c_str()); element->SetAttribute("border_radius", borderRadius.c_str()); element->SetAttribute("border_style", borderStyle.c_str()); element->SetAttribute("opacity", opacity.c_str()); Loading Loading @@ -556,6 +560,9 @@ extern "C" { const char* loaded_class = xml_data->Attribute("css_class"); if (loaded_class) cssClass = loaded_class; const char* loaded_id = xml_data->Attribute("css_id"); if (loaded_id) cssId = loaded_id; const char* loaded_br = xml_data->Attribute("border_radius"); if (loaded_br) borderRadius = loaded_br; Loading Loading @@ -743,6 +750,7 @@ extern "C" { json_object *obj = json_object_new_object(); json_object_object_add(obj, "background_color", json_object_new_string(backgroundColor.c_str())); json_object_object_add(obj, "css_class", json_object_new_string(cssClass.c_str())); json_object_object_add(obj, "css_id", json_object_new_string(cssId.c_str())); json_object_object_add(obj, "border_radius", json_object_new_string(borderRadius.c_str())); json_object_object_add(obj, "border_style", json_object_new_string(borderStyle.c_str())); json_object_object_add(obj, "opacity", json_object_new_string(opacity.c_str())); Loading Loading @@ -829,6 +837,10 @@ extern "C" { val = json_object_get_string(val_obj); if (val) cssClass = val; } if (json_object_object_get_ex(obj, "css_id", &val_obj)) { val = json_object_get_string(val_obj); if (val) cssId = val; } if (json_object_object_get_ex(obj, "border_radius", &val_obj)) { val = json_object_get_string(val_obj); if (val) borderRadius = val; Loading Loading @@ -1219,6 +1231,8 @@ extern "C" { cls = cssClass + " " + responsiveClass; } cnt.setAttribute("class", cls.c_str()); std::string customCssId = sanitizeCssId(cssId); cnt.setAttribute("id", (customCssId.empty() ? responsiveClass : customCssId).c_str()); if (!dataAttrs.empty()) applyDataAttrs(cnt, dataAttrs); // Shape divider: a decorative wave/oval SVG pinned to the Loading Loading @@ -1433,6 +1447,8 @@ extern "C" { bool haveChilds() override { return child != nullptr; } std::string getCssId() const override { return sanitizeCssId(cssId); } /** * @brief Sets the first child element of this container. * @param el The EditPlugin element to be set as the first child. Loading
editor/widgets/faq/faq.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "plugin.h" #include "translations.h" #include "llms_text.h" #include "../common/css_id.h" extern "C" { namespace blogi::webedit { Loading @@ -53,6 +54,7 @@ extern "C" { // Container styling std::string title = ""; std::string cssId = ""; std::string titleFontSize = "24px"; std::string titleColor = "var(--blogi-text)"; std::string paddingTop = "0"; Loading Loading @@ -246,6 +248,7 @@ extern "C" { addField("title_font_size", "Title Font Size", "text", "24px", "desktop"); addField("title_color", "Title Color (Dark)", "color_var", nullptr, "all", nullptr, "simple"); addField("l_title_color", "Title Color (Light)", "color_var", nullptr, "light", nullptr, "simple"); addField("css_id", "CSS ID", "text", "e.g. my-faq"); addSpacingBox("padding", "Padding", "desktop"); addField("max_width", "Max Width", "text", "e.g. 800px"); addField("columns", "Spalten", "select", nullptr, "desktop", mkOpts({"1","2","3","4"}), "simple"); Loading Loading @@ -336,6 +339,7 @@ extern "C" { element->SetAttribute("type_id", getTypeId().c_str()); element->SetAttribute("title", title.c_str()); element->SetAttribute("css_id", cssId.c_str()); element->SetAttribute("title_font_size", titleFontSize.c_str()); element->SetAttribute("title_color", titleColor.c_str()); element->SetAttribute("padding_top", paddingTop.c_str()); Loading Loading @@ -399,6 +403,7 @@ extern "C" { const char *val = nullptr; val = xml_data->Attribute("title"); if (val) title = val; val = xml_data->Attribute("css_id"); if (val) cssId = val; val = xml_data->Attribute("title_font_size"); if (val) titleFontSize = val; val = xml_data->Attribute("title_color"); if (val) titleColor = val; // Legacy migration: pre-split documents stored padding as a Loading Loading @@ -493,6 +498,7 @@ extern "C" { json_object *obj = json_object_new_object(); json_object_object_add(obj, "title", json_object_new_string(title.c_str())); json_object_object_add(obj, "css_id", json_object_new_string(cssId.c_str())); json_object_object_add(obj, "title_font_size", json_object_new_string(titleFontSize.c_str())); json_object_object_add(obj, "title_color", json_object_new_string(titleColor.c_str())); json_object_object_add(obj, "padding_top", json_object_new_string(paddingTop.c_str())); Loading Loading @@ -583,6 +589,7 @@ extern "C" { }; strNonEmpty("title", title); str("css_id", cssId); strNonEmpty("title_font_size", titleFontSize); strNonEmpty("title_color", titleColor); str("padding_top", paddingTop); Loading Loading @@ -685,6 +692,8 @@ extern "C" { // Outer container libhtmlpp::HtmlElement outer("div"); outer.setAttribute("class", (rc + "-faq").c_str()); std::string customCssId = sanitizeCssId(cssId); outer.setAttribute("id", (customCssId.empty() ? rc : customCssId).c_str()); outer.setAttribute("itemscope", ""); outer.setAttribute("itemtype", "https://schema.org/FAQPage"); Loading Loading @@ -907,6 +916,8 @@ extern "C" { bool canHaveChildren() const override { return false; } bool haveChilds() override { return false; } std::string getCssId() const override { return sanitizeCssId(cssId); } void setChildElement(const EditPlugin &) override {} void unsetChildElement(const EditPlugin &) override {} void addNextElement(const EditPlugin &) override {} Loading
editor/widgets/googlereviews/googlereviews.cpp +61 −4 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ #include <json-c/json.h> #include <plugin.h> #include "../common/css_id.h" namespace blogi { namespace webedit { Loading @@ -21,6 +22,11 @@ namespace blogi { void logError(const std::string& message) override {} private: std::string cssId = ""; public: void JsonApi(json_object *request, json_object *response) override { json_object *action_obj = nullptr; const char *action = nullptr; Loading @@ -29,13 +35,18 @@ namespace blogi { } if (!action) return; if (strcmp(action, "read") == 0) { if (strcmp(action, "modify_bulk") == 0) { json_object *props_obj = nullptr; if (json_object_object_get_ex(request, "properties", &props_obj)) { const char *s = json_object_to_json_string_ext(props_obj, JSON_C_TO_STRING_NOSLASHESCAPE); if (s) fromPropertiesJson(s); } } else if (strcmp(action, "read") == 0) { json_object *result_obj = json_object_new_object(); json_object_object_add(result_obj, "properties", json_object_new_string("{}")); json_object_object_add(result_obj, "properties", json_object_new_string(toPropertiesJson().c_str())); if (response) json_object_object_add(response, "data", result_obj); } else if (strcmp(action, "get_schema") == 0) { json_object *arr = json_object_new_array(); if (response) json_object_object_add(response, "schema", arr); if (response) json_object_object_add(response, "schema", getSchemaJson()); } if (response != nullptr) { Loading @@ -44,9 +55,48 @@ namespace blogi { } } json_object* getSchemaJson() { json_object *arr = json_object_new_array(); auto addField = [&](const char *key, const char *label, const char *type, const char *placeholder = nullptr, const char *target = "all", const char *level = "expert") { json_object *f = json_object_new_object(); json_object_object_add(f, "key", json_object_new_string(key)); json_object_object_add(f, "label", json_object_new_string(label)); json_object_object_add(f, "type", json_object_new_string(type)); if (placeholder) json_object_object_add(f, "placeholder", json_object_new_string(placeholder)); json_object_object_add(f, "target", json_object_new_string(target)); json_object_object_add(f, "level", json_object_new_string(level)); json_object_array_add(arr, f); }; addField("css_id", "CSS ID", "text", "e.g. my-reviews"); return arr; } std::string toPropertiesJson() { json_object *obj = json_object_new_object(); json_object_object_add(obj, "css_id", json_object_new_string(cssId.c_str())); std::string s = json_object_to_json_string_ext(obj, JSON_C_TO_STRING_NOSLASHESCAPE); json_object_put(obj); return s; } void fromPropertiesJson(const std::string &json) { json_object *obj = json_tokener_parse(json.c_str()); if (!obj) return; json_object *val_obj = nullptr; const char *val = nullptr; if (json_object_object_get_ex(obj, "css_id", &val_obj)) { val = json_object_get_string(val_obj); if (val) cssId = val; } json_object_put(obj); } tinyxml2::XMLElement* toXmlObject(tinyxml2::XMLDocument* doc) override { tinyxml2::XMLElement* el = doc->NewElement("GoogleReviews"); el->SetAttribute("id", Id.c_str()); el->SetAttribute("css_id", cssId.c_str()); return el; } Loading @@ -55,7 +105,12 @@ namespace blogi { uuid::uuid newId; if(newId.parse(id_attr)) Id = newId; } if (const char *css_id_attr = xml_data->Attribute("css_id")) { cssId = css_id_attr; } } std::string getCssId() const override { return sanitizeCssId(cssId); } bool canHaveChildren() const override { return false; } Loading @@ -65,6 +120,8 @@ namespace blogi { void Render(libhtmlpp::HtmlElement &el) const override { std::string uid = "gr_" + std::string(Id.c_str()); std::string customCssId = sanitizeCssId(cssId); if (!customCssId.empty()) uid = customCssId; std::string responsiveClass = std::string("we-") + getInstanceId().c_str(); libhtmlpp::HtmlElement *container = new libhtmlpp::HtmlElement("div"); Loading