Commit de0f3bc1 authored by Jan Koester's avatar Jan Koester
Browse files

custom css id now possible

parent c31f9ddf
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -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 {
@@ -96,6 +97,9 @@ extern "C" {
            bool hidden   = false;
            bool m_hidden = false;

            // Custom CSS ID
            std::string cssId = "";

            // Custom CSS
            std::string customCss = "";

@@ -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");
                {
@@ -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");

@@ -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");
@@ -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()));
@@ -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);
@@ -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 + ";";
@@ -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; }
+15 −1
Original line number Diff line number Diff line
@@ -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 {
@@ -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 = "";
@@ -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");
@@ -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());
@@ -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");
@@ -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()));
@@ -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;
@@ -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") {
@@ -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);
            }
+16 −0
Original line number Diff line number Diff line
@@ -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 {
@@ -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 = "";
@@ -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");
@@ -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());
@@ -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;

@@ -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()));
@@ -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;
@@ -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
@@ -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.
+11 −0
Original line number Diff line number Diff line
@@ -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 {
@@ -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";
@@ -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");
@@ -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());
@@ -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
@@ -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()));
@@ -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);
@@ -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");

@@ -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 {}
+61 −4
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
#include <json-c/json.h>

#include <plugin.h>
#include "../common/css_id.h"

namespace blogi {
    namespace webedit {
@@ -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;
@@ -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) {
@@ -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;
            }

@@ -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; }

@@ -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