Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
emersonfelipesp opened this issue Feb 24, 2022 · 5 comments · Fixed by #8734
Assignees
Labels
status: accepted This issue has been accepted for implementation type: feature Introduction of new functionality to the application

Comments

@emersonfelipesp
Copy link
Contributor

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

@jeremystretch
Copy link
Member

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 jeremystretch added the status: under review Further discussion is needed to determine this issue's scope and/or implementation label Feb 25, 2022
@emersonfelipesp
Copy link
Contributor Author

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.

@jeremystretch
Copy link
Member

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.

@emersonfelipesp
Copy link
Contributor Author

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
Copy link
Contributor Author

@jeremystretch is it ok this way?

@jeremystretch jeremystretch added status: accepted This issue has been accepted for implementation and removed status: under review Further discussion is needed to determine this issue's scope and/or implementation labels Mar 4, 2022
jeremystretch added a commit that referenced this issue Mar 4, 2022
Closes #8733: Add {% block pluginfooter %} to 'base/layout.html' template
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 3, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
status: accepted This issue has been accepted for implementation type: feature Introduction of new functionality to the application
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants