Issue with Django CMS Icon Module: Missing Static Path and Extra

ghz 8months ago ⋅ 145 views

Issue with Django CMS Icon Module: Missing Static Path and Extra Class in Generated Markup

I am attempting to utilize the djangocms-icon module to incorporate my own SVG icons into my Django CMS project. Following the documentation, I have successfully added Material Design icons. However, I encounter issues when adding my custom SVG icons.

In my settings.py, I added the following code:

with open('iconset.json') as fh:
    ICONSET = fh.read()

DJANGOCMS_ICON_SETS = [
    ('fontawesome5regular', 'far', 'Font Awesome 5 Regular', 'latest'),
    ('fontawesome5solid', 'fas', 'Font Awesome 5 Solid', 'latest'),
    ('fontawesome5brands', 'fab', 'Font Awesome 5 Brands', 'latest'),
    ('materialdesign', 'zmdi', 'Material Design'),
    (ICONSET, 'svg-icon', 'My Icons'),
]

DJANGOCMS_ICON_TEMPLATES = [
    ('svg', 'SVG template'),
]

I have created an iconset.json file at the root of my project:

{
    "svg": true,
    "spritePath": "sprites/icons.svg",
    "iconClass": "svg-icon",
    "iconClassFix": "svg-icon-",
    "icons": [
        "svg-icon-card",
        "svg-icon-card-add"
    ]
}

I have also created my icons.svg file in static/sprites/icons.svg:

<svg width="0" height="0" class="hidden">
  <symbol xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" id="svg-icon-card">
    <!-- path data -->
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" id="svg-icon-card-add">
    <!-- path data -->
  </symbol>
</svg>

Additionally, I created templates/djangocms_icon/svg/icon.html:

{% load cms_tags static %}
<span class="icon {{ instance.attributes.class }}">
    <svg role="presentation">
        <use xlink:href="{% static 'sprites/icons.svg' %}#{{ instance.icon }}"></use>
    </svg>
</span>

The issue arises in the generated markup. In the icon addition widget inspection, there is a missing /static/ before sprites/icons.svg#svg-icon-card. Additionally, in the page render, there is an extra svg-icon class after the # in the xlink. The generated markup looks like this:

<span class="djangocms-svg-icon svg-icon svg-icon-card">
    <svg role="presentation">
        <use xlink:href="sprites/icons.svg#svg-icon-card"></use>
    </svg>
</span>

There is a missing /static/ before sprites/icons.svg#svg-icon-card.

There also an issue in my rendered page with an extra "svg-icon " after the # in the xlink.

<span class="icon  cms-plugin cms-plugin-3730">
    <svg role="presentation">
        <use xlink:href="/static/sprites/icons.svg#svg-icon svg-icon-card"></use>
    </svg>
</span>

How can I resolve these issues?

I expected my icon to render in both my icon-picker and my rendered page but since the xlink do not find the path, nothing is shown.

Answers

The issue you're encountering seems to be related to how the static file paths are being resolved in your Django project. Let's address each problem:

  1. Missing /static/ in the xlink:href attribute:

    The static template tag should include the /static/ prefix automatically. However, in your icon.html template, you're using the {% static %} tag directly within the xlink:href attribute. Instead, you should use it outside the attribute to construct the full URL:

    <use xlink:href="{% static 'sprites/icons.svg' %}#{{ instance.icon }}"></use>
    
  2. Extra svg-icon class in the xlink:href attribute:

    It seems that the svg-icon class is being added twice in the xlink:href attribute. This is likely due to how you're constructing the iconClass in your iconset.json. Make sure that you're not duplicating the class.

    Additionally, you can remove the iconClass from the iconset.json and directly append it in your template:

    <use xlink:href="{% static 'sprites/icons.svg' %}#{{ instance.icon }} {{ instance.attributes.class }}"></use>
    

    This way, you have more control over the classes added to the xlink:href.

  3. Ensure proper loading of the iconset.json:

    Make sure that the iconset.json file is located at the root of your project and that the file path is correctly specified in your settings.

By addressing these issues, you should be able to resolve the problems with rendering your custom SVG icons in both the icon-picker and the rendered page. After making these changes, reload your Django CMS project and verify that the icons are displayed correctly.