Add Jinja2 block {% block pluginfooter %} inside <footer> html tag on 'base/layout.html' template #6139

Closed
opened 2025-12-29 19:37:15 +01:00 by adam · 5 comments
Owner

Originally created by @emersonfelipesp on GitHub (Feb 24, 2022).

Originally assigned to: @emersonfelipesp on GitHub.

NetBox version

v3.1.8

Feature type

New functionality

Proposed functionality

The functionality allows netbox plugin developers to easily create its own footer navigation to link to many useful links, like Source Code, Plugin documentation, etc.

Use case

I am the main developer of Proxbox plugin and could not find a easy way to insert code inside Netbox footer to link to my own links, so that the community could easily found my code and documentation.

As a workaround, I created my own layout template and changed the settings.py so that Django looks for that template and it solved my issue. The whole thing is that it was more complicated than it should be and I also had to modify the core Netbox code by changing the settings.py, which I did not like to do, as it adds one more step to make the plugin work properly and makes things easy to break.


Bellow some of the code I did as workaround:

TEMPLATES_DIR = BASE_DIR + '/templates'

# PROXBOX CUSTOM TEMPLATE
PROXBOX_TEMPLATE_DIR = BASE_DIR + '/netbox-proxbox/netbox_proxbox/templates/netbox_proxbox'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [TEMPLATES_DIR, PROXBOX_TEMPLATE_DIR],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.template.context_processors.media',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'netbox.context_processors.settings_and_registry',
            ],
        },
    },
]

How it actually looks like

Light mode:
proxbox-footer-light-mode
proxbox-footer-light-mode_02

Dark mode:
proxbox-footer-dark-mode

Database changes

No response

External dependencies

No response

Originally created by @emersonfelipesp on GitHub (Feb 24, 2022). Originally assigned to: @emersonfelipesp on GitHub. ### NetBox version v3.1.8 ### Feature type New functionality ### Proposed functionality The functionality allows netbox plugin developers to easily create its own footer navigation to link to many useful links, like Source Code, Plugin documentation, etc. ### Use case ## Plugin custom links inside footer I am the main developer of **[Proxbox plugin](https://github.com/N-Multifibra/netbox-proxbox)** and could not find a easy way to insert code inside Netbox footer to link to my own links, so that the community could easily found my code and documentation. As a workaround, I created my own layout template and changed the [settings.py](https://github.com/netbox-community/netbox/blob/develop/netbox/netbox/settings.py) so that Django looks for that template and it solved my issue. The whole thing is that it was more complicated than it should be and I also had to modify the core Netbox code by changing the [settings.py](https://github.com/netbox-community/netbox/blob/develop/netbox/netbox/settings.py), which I did not like to do, as it adds one more step to make the plugin work properly and makes things easy to break. --- ### Bellow some of the code I did as workaround: - [Proxbox layout template (proxbox_layout.html)](https://github.com/N-Multifibra/netbox-proxbox/blob/develop/netbox_proxbox/templates/netbox_proxbox/proxbox_layout.html) which basically copies '**[base/layout.html](https://github.com/netbox-community/netbox/blob/develop/netbox/templates/base/layout.html)**' and adds the block I am requesting. - [proxmox_vm_full_update.html](https://github.com/N-Multifibra/netbox-proxbox/blob/develop/netbox_proxbox/templates/netbox_proxbox/proxmox_vm_full_update.html) and [proxmox_vm_list.html](https://github.com/N-Multifibra/netbox-proxbox/blob/develop/netbox_proxbox/templates/netbox_proxbox/proxmox_vm_list.html) that are templates using the proxbox layout template. - Change to [settings.py](https://github.com/netbox-community/netbox/blob/develop/netbox/netbox/settings.py) so that Django uses my proxbox template: ```python TEMPLATES_DIR = BASE_DIR + '/templates' # PROXBOX CUSTOM TEMPLATE PROXBOX_TEMPLATE_DIR = BASE_DIR + '/netbox-proxbox/netbox_proxbox/templates/netbox_proxbox' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [TEMPLATES_DIR, PROXBOX_TEMPLATE_DIR], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.template.context_processors.media', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'netbox.context_processors.settings_and_registry', ], }, }, ] ``` --- ### How it actually looks like **Light mode:** ![proxbox-footer-light-mode](https://user-images.githubusercontent.com/24397251/155451884-dc905764-b834-4c8d-a068-c190306376bb.png) ![proxbox-footer-light-mode_02](https://user-images.githubusercontent.com/24397251/155452359-5c91e2ad-018e-442c-91fb-6c6fe105279c.png) **Dark mode:** ![proxbox-footer-dark-mode](https://user-images.githubusercontent.com/24397251/155451420-211e4c29-62cf-4a9e-9700-70e2dffb5ccc.png) ### Database changes _No response_ ### External dependencies _No response_
adam added the status: acceptedtype: feature labels 2025-12-29 19:37:15 +01:00
adam closed this issue 2025-12-29 19:37:15 +01:00
Author
Owner

@jeremystretch commented on GitHub (Feb 25, 2022):

Rather than add a pluginfooter block, IMO it would be preferable to wrap the current footer in a footer block which can then be overridden by a downstream template. It probably also makes sense to add a child block within this specifically for the footer links. This allows a plugin author to do something like this to add a custom link/icon to the footer:

{% block footer_links %}
  {{ block.super }}
  <a type="button" class="nav-link" href="{% url 'whatever' %}" target="_blank">
    <i title="Docs" class="mdi mdi-some-icon text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i>
  </a>
{% endblock %}
@jeremystretch commented on GitHub (Feb 25, 2022): Rather than add a `pluginfooter` block, IMO it would be preferable to wrap the current footer in a `footer` block which can then be overridden by a downstream template. It probably also makes sense to add a child block within this specifically for the footer links. This allows a plugin author to do something like this to add a custom link/icon to the footer: ``` {% block footer_links %} {{ block.super }} <a type="button" class="nav-link" href="{% url 'whatever' %}" target="_blank"> <i title="Docs" class="mdi mdi-some-icon text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> </a> {% endblock %} ```
Author
Owner

@emersonfelipesp commented on GitHub (Feb 25, 2022):

I agree with this way, didn't know the .super feature.

But even doing like this, it would be possible to add a entire navigation like I did or only buttons to the existing navigation?
I think adding a new navigation is better as it keeps things more readable and separated from the core Netbox. But I am not totally certain about it.

@emersonfelipesp commented on GitHub (Feb 25, 2022): I agree with this way, didn't know the `.super` feature. But even doing like this, it would be possible to add a entire navigation like I did or only buttons to the existing navigation? I think adding a new navigation is better as it keeps things more readable and separated from the core Netbox. But I am not totally certain about it.
Author
Owner

@jeremystretch commented on GitHub (Feb 25, 2022):

I don't think it really makes sense to add a second footer like that; it looks odd and will likely lead to rendering issues. But, by introducing both footer and footer_links blocks, we still preserve that flexibility. Something like this:

<footer class="footer container-fluid">
  {% block footer %}
    <div class="row align-items-center justify-content-between mx-0">
  
      <div class="col-sm-12 col-md-auto fs-4 noprint">
        <nav class="nav justify-content-center justify-content-lg-start">
          {% block footer_links %}
            <!-- Built-in footer links -->
          {% endblock footer_links %}
        </nav>
      </div>
  
      <div class="col-sm-12 col-md-auto text-center text-lg-end text-muted">
        <span class="d-block d-md-inline">{% annotated_now %} {% now 'T' %}</span>
        <span class="ms-md-3 d-block d-md-inline">{{ settings.HOSTNAME }} (v{{ settings.VERSION }})</span>
      </div>
  
    </div>
  {% endblock footer %}
</footer>

This allows a downstream template to either override/extend only the footer links, or the entire footer, by overriding the footer_links or footer block respectively.

@jeremystretch commented on GitHub (Feb 25, 2022): I don't think it really makes sense to add a second footer like that; it looks odd and will likely lead to rendering issues. But, by introducing both `footer` and `footer_links` blocks, we still preserve that flexibility. Something like this: ``` <footer class="footer container-fluid"> {% block footer %} <div class="row align-items-center justify-content-between mx-0"> <div class="col-sm-12 col-md-auto fs-4 noprint"> <nav class="nav justify-content-center justify-content-lg-start"> {% block footer_links %} <!-- Built-in footer links --> {% endblock footer_links %} </nav> </div> <div class="col-sm-12 col-md-auto text-center text-lg-end text-muted"> <span class="d-block d-md-inline">{% annotated_now %} {% now 'T' %}</span> <span class="ms-md-3 d-block d-md-inline">{{ settings.HOSTNAME }} (v{{ settings.VERSION }})</span> </div> </div> {% endblock footer %} </footer> ``` This allows a downstream template to either override/extend only the footer links, or the entire footer, by overriding the `footer_links` or `footer` block respectively.
Author
Owner

@emersonfelipesp commented on GitHub (Feb 26, 2022):

New custom links using dropdown list

I have just found a solution that kinds of merge our ideas. I think it got better than the first version and I hope you also like it! I used exactly the last code you sent including the footer and footer_links blocks and tried to apply to my code.

Code

{# Page footer #}
<footer class="footer container-fluid">
    {% block footer %}
        <div class="row align-items-center justify-content-between mx-0">
        
            <div class="col-sm-12 col-md-auto fs-4 noprint">
                <nav class="nav justify-content-center justify-content-lg-start">
                    {# Documentation #}
                    <a type="button" class="nav-link" href="{% static 'docs/' %}" target="_blank">
                      <i title="Docs" class="mdi mdi-book-open-variant text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i>
                    </a>
    
                    {# REST API #}
                    <a type="button" class="nav-link" href="{% url 'api-root' %}" target="_blank">
                      <i title="REST API" class="mdi mdi-cloud-braces text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i>
                    </a>
    
                    {# API docs #}
                    <a type="button" class="nav-link" href="{% url 'api_docs' %}" target="_blank">
                      <i title="REST API documentation" class="mdi mdi-book text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i>
                    </a>
    
                    {# GraphQL API #}
                    {% if config.GRAPHQL_ENABLED %}
                      <a type="button" class="nav-link" href="{% url 'graphql' %}" target="_blank">
                        <i title="GraphQL API" class="mdi mdi-graphql text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i>
                      </a>
                    {% endif %}
    
                    {# GitHub #}
                    <a type="button" class="nav-link" href="https://github.com/netbox-community/netbox" target="_blank">
                      <i title="Source Code" class="mdi mdi-github text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i>
                    </a>
    
                    {# NetDev Slack #}
                    <a type="button" class="nav-link" href="https://netdev.chat/" target="_blank">
                      <i title="Community" class="mdi mdi-slack text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i>
                    </a>

                    {% block footer_links %}

                        {# Proxbox Custom Links #}
                        <li class="nav-item dropdown dropup">
                            <a type="button" class="nav-link dropdown-toggle text-primary" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                                <i title="Proxbox Plugin" class="mdi mdi-puzzle" data-bs-placement="top" data-bs-toggle="tooltip"></i>
                            </a>
                            <ul class="dropdown-menu disabled" aria-labelledby="navbarDropdown">
                                <li>
                                    {# Proxbox - Documentation #}
                                    <a type="button" class="dropdown-item" href="https://github.com/N-Multifibra/netbox-proxbox/blob/develop/README.md" target="_blank">
                                        <i title="Proxbox | Docs" class="mdi mdi-book-open-variant text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i>  Docs
                                    </a>
                                <li>
                                    {# Proxbox - GitHub #}
                                    <a type="button" class="dropdown-item" href="https://github.com/N-Multifibra/netbox-proxbox" target="_blank">
                                        <i title="Proxbox | Source Code" class="mdi mdi-github text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> GitHub
                                    </a>
                                </li>
                                <li>
                                    {# Proxbox - Telegram (Brazil) #}
                                    <a type="button" class="dropdown-item" href="https://t.me/netboxbr" target="_blank">
                                        <i title="Proxbox | Telegram (Brazil)" class="mdi mdi-telegram text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> Telegram (BR)
                                    </a>
                                </li>
                                <li>
                                    <hr class="dropdown-divider">
                                </li>
                                <li>
                                    <span class="dropdown-item disabled">Proxbox (v0.0.3)</span>
                                </li>
                            </ul>
                        </li>
                        
                    {% endblock footer_links %}
                </nav>
            </div>
        
            <div class="col-sm-12 col-md-auto text-center text-lg-end text-muted">
                <span class="d-block d-md-inline">{% annotated_now %} {% now 'T' %}</span>
                <span class="ms-md-3 d-block d-md-inline">{{ settings.HOSTNAME }} (v{{ settings.VERSION }})</span>
            </div>

        </div>
    {% endblock footer %}
</footer>

How it actually looks like

Light mode

proxbox_new_footer_light_02
proxbox_new_footer_light

Dark mode

proxbox_new_footer_dark_02
proxbox_new_footer_dark

@emersonfelipesp commented on GitHub (Feb 26, 2022): # New custom links using dropdown list I have just found a solution that kinds of merge our ideas. I think it got better than the first version and I hope you also like it! I used exactly the last code you sent including the `footer` and `footer_links` blocks and tried to apply to my code. ## Code ```python {# Page footer #} <footer class="footer container-fluid"> {% block footer %} <div class="row align-items-center justify-content-between mx-0"> <div class="col-sm-12 col-md-auto fs-4 noprint"> <nav class="nav justify-content-center justify-content-lg-start"> {# Documentation #} <a type="button" class="nav-link" href="{% static 'docs/' %}" target="_blank"> <i title="Docs" class="mdi mdi-book-open-variant text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> </a> {# REST API #} <a type="button" class="nav-link" href="{% url 'api-root' %}" target="_blank"> <i title="REST API" class="mdi mdi-cloud-braces text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> </a> {# API docs #} <a type="button" class="nav-link" href="{% url 'api_docs' %}" target="_blank"> <i title="REST API documentation" class="mdi mdi-book text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> </a> {# GraphQL API #} {% if config.GRAPHQL_ENABLED %} <a type="button" class="nav-link" href="{% url 'graphql' %}" target="_blank"> <i title="GraphQL API" class="mdi mdi-graphql text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> </a> {% endif %} {# GitHub #} <a type="button" class="nav-link" href="https://github.com/netbox-community/netbox" target="_blank"> <i title="Source Code" class="mdi mdi-github text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> </a> {# NetDev Slack #} <a type="button" class="nav-link" href="https://netdev.chat/" target="_blank"> <i title="Community" class="mdi mdi-slack text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> </a> {% block footer_links %} {# Proxbox Custom Links #} <li class="nav-item dropdown dropup"> <a type="button" class="nav-link dropdown-toggle text-primary" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false"> <i title="Proxbox Plugin" class="mdi mdi-puzzle" data-bs-placement="top" data-bs-toggle="tooltip"></i> </a> <ul class="dropdown-menu disabled" aria-labelledby="navbarDropdown"> <li> {# Proxbox - Documentation #} <a type="button" class="dropdown-item" href="https://github.com/N-Multifibra/netbox-proxbox/blob/develop/README.md" target="_blank"> <i title="Proxbox | Docs" class="mdi mdi-book-open-variant text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> Docs </a> <li> {# Proxbox - GitHub #} <a type="button" class="dropdown-item" href="https://github.com/N-Multifibra/netbox-proxbox" target="_blank"> <i title="Proxbox | Source Code" class="mdi mdi-github text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> GitHub </a> </li> <li> {# Proxbox - Telegram (Brazil) #} <a type="button" class="dropdown-item" href="https://t.me/netboxbr" target="_blank"> <i title="Proxbox | Telegram (Brazil)" class="mdi mdi-telegram text-primary" data-bs-placement="top" data-bs-toggle="tooltip"></i> Telegram (BR) </a> </li> <li> <hr class="dropdown-divider"> </li> <li> <span class="dropdown-item disabled">Proxbox (v0.0.3)</span> </li> </ul> </li> {% endblock footer_links %} </nav> </div> <div class="col-sm-12 col-md-auto text-center text-lg-end text-muted"> <span class="d-block d-md-inline">{% annotated_now %} {% now 'T' %}</span> <span class="ms-md-3 d-block d-md-inline">{{ settings.HOSTNAME }} (v{{ settings.VERSION }})</span> </div> </div> {% endblock footer %} </footer> ``` --- ## How it actually looks like ### Light mode ![proxbox_new_footer_light_02](https://user-images.githubusercontent.com/24397251/155827301-967631bb-3590-435b-87e2-7a0e67285edf.png) ![proxbox_new_footer_light](https://user-images.githubusercontent.com/24397251/155827303-70e0ed3b-a7c9-42a3-bbe5-b5df1caf1ffc.png) ### Dark mode ![proxbox_new_footer_dark_02](https://user-images.githubusercontent.com/24397251/155827306-4b11a403-30ec-4ce5-9e8d-3a372acf2484.png) ![proxbox_new_footer_dark](https://user-images.githubusercontent.com/24397251/155827309-7fdc9895-4c20-4a1e-8bac-54a2342893a1.png)
Author
Owner

@emersonfelipesp commented on GitHub (Mar 2, 2022):

@jeremystretch is it ok this way?

@emersonfelipesp commented on GitHub (Mar 2, 2022): @jeremystretch is it ok this way?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#6139