Flask conflict whit use {% extends "base.html" %}

Flask conflict whit use {% extends "base.html" %}

aavilesaaviles Posts: 5Questions: 2Answers: 0

Hi all;

I am having trouble implementing Datatables with Flask & Bootstrap.

When in my base.html file I add the lines: {% extends "bootstrap / base.html"%}

{% extends "bootstrap/base.html" %}
<head>
   {% block styles%}
   {{Super()}}
     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
    <link href='https://cdn.datatables.net/1.10.24/css/jquery.dataTables.min.css' rel='stylesheet' type='text/css'>
    <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
    <script src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js"></script>
{% endblock%}

It does not work, but if I remove them it works, has it happened to someone? And what solution did they have?.


app.py :

from collections import Counter
from flask import Flask, render_template
from flask_bootstrap import Bootstrap
import switchdb
app = Flask(__name__)
@app.route("/allports", methods=['GET','POST'])

def allports():
    switchdata = AllInterfaceDetail()
    return render_template("allports.html", switches=switchdata, lastupdate=lastupdate)

def AllInterfaceDetail():
    """
    Query DB for summary info for all interfaces
    """
    swDB = switchdb.DB()
    raw_info = swDB.getAllInterfaceDetail()
    switchList = []
    for row in raw_info:
        row = list(row)
        switch = {}
        switch["int_name"] = row[0]
        switch["description"] = row[1]
        switch["phys_address"] = row[2]
        switch["oper_status"] = row[3]
        switchList.append(switch)
    swDB.close()
    return switchList

if __name__ == "__main__":
    Bootstrap(app)
    app.run(debug=True)

**base.html******
without {% extends "bootstrap/base.html" %}

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>MAC Tools </title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
    <link href='https://cdn.datatables.net/1.10.24/css/jquery.dataTables.min.css' rel='stylesheet' type='text/css'>
    <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
    <script src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js"></script>
</head>
<body>
    <br/>
    <div class="container">
        {% block content %}
        {% endblock %}
    </div>
</body>
</html>
    <script>
        $(document).ready(function () {
            $('#example').DataTable({
                searching: true,
                "aLengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],
                "iDisplayLength": 10
            }
            );
        });
    </script>

base.html
whit {% extends "bootstrap/base.html" %}

{% extends "bootstrap/base.html" %}
<head>
   {% block styles %}
   {{super()}}
   <link rel="stylesheet" href="{{url_for('static', filename='bootstrap.css')}}">
   <link href='https://cdn.datatables.net/1.10.24/css/jquery.dataTables.min.css' rel='stylesheet' type='text/css'>
   <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
   <script src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js"></script>
{% endblock %}
<!-- IMG -->
<link rel="icon" type="image/png" href="static/cli.png">
   {% block title %}
   {% if title %}
      {{ title }}
   {% else %}
      Switch Port Utilization
   {% endif %}
   {% endblock %}
   {% include 'nav.html' %}
</head>
   <script>
      $(document).ready(function () {
         $('#example').DataTable({
            searching: true,
            "ordering": true,
            "aLengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],
            "iDisplayLength": 10
         }
         );
      });
   </script>

allports.html

{% extends "base.html" %} 
{% block content %}
<body>
   <div class="row justify-content-between align-items-right">
      <div class="col-lg-auto"></div>
      <div class="col-lg-auto"></div>
      <div class="col-lg-auto">
         <div class="alert alert-dismissible alert-info">
            <button type="button" class="close" data-dismiss="alert">&times;</button>
            Last updated: <strong>{{ lastupdate }}</strong>
         </div>
      </div>
   </div>
   <div class="container">
      <div class="col-lg-12">
         <div class="page-header">
            <h3>Current Ports Status</h3>
         </div>
      </div>
   </br>
   </div>
   <div class="container">
      <table id="example" class="table table-striped table-hover">
         <thead>
            <tr>
               <th scope="col">Interface Name</th>
               <th scope="col">Description</th>
               <th scope="col">Mac Address</th>
               <th scope="col">State</th>
               <th scope="col">off/on</th>
            </tr>
         </thead>
         <tbody>
            {% for switch in switches %}
            <tr>
               <td>{{ switch.int_name }}</td>
               <td>{{ switch.description }}</td>
               <td>{{ switch.phys_address }}</td>
               <td>
                  {% if switch.oper_status == 'up' %}
                  <p class="text-success">Up</span>
                     {% else %}
                  <p class="text-danger">Down</span>
                     {% endif %}
               </td>
               <td>
                  <label class="toggle">
                     {% if switch.oper_status == 'up' %}
                     <input type="checkbox" checked />
                     {% else %}
                     <input type="checkbox" />
                     {% endif %}
                     <span class="slider round"></span>
                  </label>
               </td>

            </tr>
            {% endfor %}
         </tbody>
      </table>
   </div>
{% endblock %}
</body>

Thank you very much for reading me, and I appreciate your help

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 61,697Questions: 1Answers: 10,102 Site admin

    What does the rendered HTML look like (i.e. View source)? If you could link to a test case please, I'd be happy to take a look and try to help.

    Alla

  • aavilesaaviles Posts: 5Questions: 2Answers: 0

    Hello Alla !! Thank you very much for answering my question, and of course I provide you with the information: ,

    allports.html with {% extends "bootstrap / base.html"%}

    <header>
        <nav id="navbar_top" class="navbar navbar-expand-lg navbar-dark bg-primary">
           <div class="container">
              <img class="navbar-brand" href="/switchport" src="static/img/cnoc_.png"></img>
              <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#main_nav">
                 <span class="navbar-toggler-icon"></span>
              </button>
              <div class="collapse navbar-collapse" id="main_nav">
                 <ul class="navbar-nav ms-auto">
                    <li class="nav-item active"><a class="nav-link" href="/switchport"> Home <span class="sr-only"></span>(current)</a></li>
                    <li class="nav-item active"><a class="nav-link" href="/network-wide">Network-Wide Stats</a></li>
                    <li class="nav-item active"><a class="nav-link" href="/allports">Ports Stats</a></li>
                 </ul>
              </div> <!-- navbar-collapse.// -->
           </div> <!-- container-fluid.// -->
        </nav>
     </header>
     
     <script>
        document.addEventListener("DOMContentLoaded", function () {
              window.addEventListener('scroll', function () {
                 if (window.scrollY > 50) {
                    document.getElementById('navbar_top').classList.add('fixed-top');
                    // add padding top to show content behind navbar
                    navbar_height = document.querySelector('.navbar').offsetHeight;
                    document.body.style.paddingTop = navbar_height + 'px';
                 } else {
                    document.getElementById('navbar_top').classList.remove('fixed-top');
                    // remove padding top from body
                    document.body.style.paddingTop = '0';
                 }
              });
           });
     </script><!DOCTYPE html>
    <html>
      <head>
        <title>
       
          Switch Port Utilization
       
       </title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
       
        <!-- Bootstrap -->
        <link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
       <link rel="stylesheet"  href="/static/bootstrap.css">
       <lscript href="/static/js/jquery.min.js">
       <link rel="icon"  type="image/png"  href="static/cli.png">
       
      </head>
      <body>
        
        
       <div class="container">
          <div class="col-lg-12">
             <div class="page-header">
                <h1>Switch Port Detail</h1>
             </div>
          </div>
       </div>
       <div class="container">
          <div class="jumbotron">
             <div id="myTabContent" class="tab-content">
                <table class="table table-hover">
                    <thead>
                       <tr>
                          <th scope="col">Interface Name</th>
                          <th scope="col">Description</th>
                          <th scope="col">MAC Address</th>
                          <th scope="col">State</th>
                          <th scope="col">Action</th>
                       </tr>
                    </thead>
                    <tbody>
                       
                    </tbody>
              </table>
             </div>
          </div>
       </div>
       
    
        
        <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
        <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
      </body>
    </html>
    
    

    allports.html without {% extends "bootstrap / base.html"%}

    <header>
        <nav id="navbar_top" class="navbar navbar-expand-lg navbar-dark bg-primary">
           <div class="container">
              <img class="navbar-brand" href="/switchport" src="static/img/cnoc_.png"></img>
              <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#main_nav">
                 <span class="navbar-toggler-icon"></span>
              </button>
              <div class="collapse navbar-collapse" id="main_nav">
                 <ul class="navbar-nav ms-auto">
                    <li class="nav-item active"><a class="nav-link" href="/switchport"> Home <span class="sr-only"></span>(current)</a></li>
                    <li class="nav-item active"><a class="nav-link" href="/network-wide">Network-Wide Stats</a></li>
                    <li class="nav-item active"><a class="nav-link" href="/allports">Ports Stats</a></li>
                 </ul>
              </div> <!-- navbar-collapse.// -->
           </div> <!-- container-fluid.// -->
        </nav>
     </header>
     
     <script>
        document.addEventListener("DOMContentLoaded", function () {
              window.addEventListener('scroll', function () {
                 if (window.scrollY > 50) {
                    document.getElementById('navbar_top').classList.add('fixed-top');
                    // add padding top to show content behind navbar
                    navbar_height = document.querySelector('.navbar').offsetHeight;
                    document.body.style.paddingTop = navbar_height + 'px';
                 } else {
                    document.getElementById('navbar_top').classList.remove('fixed-top');
                    // remove padding top from body
                    document.body.style.paddingTop = '0';
                 }
              });
           });
     </script><!DOCTYPE html>
    <html>
      <head>
        <title>
       
          Switch Port Utilization
       
       </title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
       
        <!-- Bootstrap -->
        <link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3./css/bootstrap.min.css" rel="stylesheet">
       <link rel="stylesheet" href="/static/bootstrap.css">
       <lscript href="/static/js/jquery.min.js">
       <link rel="icon"  type="image/png"  href="static/cli.png">
       
      </head>
      <body>
        
        
       <div class="container">
          <div class="col-lg-12">
             <div class="page-header">
                <h1>Switch Port Detail</h1>
             </div>
          </div>
       </div>
       <div class="container">
          <div class="jumbotron">
             <div id="myTabContent" class="tab-content">
                <table class="table table-hover">
                    <thead>
                       <tr>
                          <th scope="col">Interface Name</th>
                          <th scope="col">Description</th>
                          <th scope="col">MAC Address</th>
                          <th scope="col">State</th>
                          <th scope="col">Action</th>
                       </tr>
                    </thead>
                    <tbody>
                       
                    </tbody>
              </table>
             </div>
          </div>
       </div>
       
    
        
        <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
        <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
      </body>
    </html>
    
    

    Regards!

  • kthorngrenkthorngren Posts: 20,297Questions: 26Answers: 4,769
    Answer ✓

    Both code snippets of allports.html look the same to me. Not seeing the base.html code.

    Line 47 looks like an error:

    <lscript href="/static/js/jquery.min.js">
    

    The <lscript> isn't right.

    You are loading jquery.js on line 84. And you are loading jquery.js on line 7 of the code snippet named base.html:

    <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
    

    You should load jquery.js only once. Loading it multiple times will causes issues with Datatables and maybe other libraries that rely on jquery.

    Since you are using Bootstrap 3 styling you should use the Datatables BS 3 integration files. See the Styling docs and this example for more information. You can use the Download builder to generate the proper set of files to use with Bootstrap 3.

    When @allan asked to see the rendered HTML I think he wanted to see some of the rows in the tbody but it looks like you removed those. Can you post a few rows?

    I put together a simple example based on your template showing the slider works with Datatables:
    http://live.datatables.net/ceseciwa/1/edit

    There is a conflicting CSS or something specific to your page causing the slider to not show. As Allan asked please post a link to your page or a test case showing the issue so we can help debug.

    Kevin

  • aavilesaaviles Posts: 5Questions: 2Answers: 0

    Thanks Kevin !!

    I removed the lines that you commented to me and I only left the ones that you recommended

    <!doctype html>
    <html lang="en">
    
    <head>
       <!--<link rel="stylesheet" href="{{url_for('static', filename='bootstrap.min.css')}}">-->
       <link rel="stylesheet" href="{{url_for('static', filename='bootstrap.css')}}">
      
       <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs5/jq-3.3.1/dt-1.10.25/b-1.7.1/b-colvis-1.7.1/b-html5-1.7.1/fc-3.3.3/fh-3.1.9/kt-2.6.2/r-2.2.9/rg-1.1.3/rr-1.2.8/sc-2.0.4/sb-1.1.0/sp-1.3.0/datatables.min.css"/>
     
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/v/bs5/jq-3.3.1/dt-1.10.25/b-1.7.1/b-colvis-1.7.1/b-html5-1.7.1/fc-3.3.3/fh-3.1.9/kt-2.6.2/r-2.2.9/rg-1.1.3/rr-1.2.8/sc-2.0.4/sb-1.1.0/sp-1.3.0/datatables.min.js"></script>
    
    </head>
    

    and the website works correctly

    regards!

    Adolph

Sign In or Register to comment.