Browse Source

Closes #1714: Standardized CSV export functionality for all object lists

Jeremy Stretch 7 years ago
parent
commit
b96e3af6c7
38 changed files with 180 additions and 285 deletions
  1. 4 9
      netbox/templates/circuits/circuit_list.html
  2. 4 8
      netbox/templates/circuits/circuittype_list.html
  3. 4 9
      netbox/templates/circuits/provider_list.html
  4. 3 5
      netbox/templates/dcim/console_connections_list.html
  5. 4 9
      netbox/templates/dcim/device_list.html
  6. 4 8
      netbox/templates/dcim/devicerole_list.html
  7. 4 9
      netbox/templates/dcim/devicetype_list.html
  8. 3 5
      netbox/templates/dcim/interface_connections_list.html
  9. 3 5
      netbox/templates/dcim/inventoryitem_list.html
  10. 4 9
      netbox/templates/dcim/manufacturer_list.html
  11. 4 8
      netbox/templates/dcim/platform_list.html
  12. 3 5
      netbox/templates/dcim/power_connections_list.html
  13. 4 9
      netbox/templates/dcim/rack_list.html
  14. 4 9
      netbox/templates/dcim/rackgroup_list.html
  15. 4 9
      netbox/templates/dcim/region_list.html
  16. 4 9
      netbox/templates/dcim/site_list.html
  17. 0 20
      netbox/templates/inc/export_button.html
  18. 4 9
      netbox/templates/ipam/aggregate_list.html
  19. 5 10
      netbox/templates/ipam/ipaddress_list.html
  20. 5 10
      netbox/templates/ipam/prefix_list.html
  21. 4 8
      netbox/templates/ipam/rir_list.html
  22. 4 8
      netbox/templates/ipam/role_list.html
  23. 5 10
      netbox/templates/ipam/vlan_list.html
  24. 4 8
      netbox/templates/ipam/vlangroup_list.html
  25. 4 10
      netbox/templates/ipam/vrf_list.html
  26. 2 4
      netbox/templates/secrets/secret_list.html
  27. 5 9
      netbox/templates/secrets/secretrole_list.html
  28. 4 9
      netbox/templates/tenancy/tenant_list.html
  29. 4 8
      netbox/templates/tenancy/tenantgroup_list.html
  30. 4 9
      netbox/templates/virtualization/cluster_list.html
  31. 4 8
      netbox/templates/virtualization/clustergroup_list.html
  32. 4 8
      netbox/templates/virtualization/clustertype_list.html
  33. 4 9
      netbox/templates/virtualization/virtualmachine_list.html
  34. 3 0
      netbox/utilities/templates/buttons/add.html
  35. 19 0
      netbox/utilities/templates/buttons/export.html
  36. 3 0
      netbox/utilities/templates/buttons/import.html
  37. 26 0
      netbox/utilities/templatetags/buttons.py
  38. 3 3
      netbox/utilities/views.py

+ 4 - 9
netbox/templates/circuits/circuit_list.html

@@ -1,19 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.circuits.add_circuit %}
-		<a href="{% url 'circuits:circuit_add' %}" class="btn btn-primary">
-			<span class="fa fa-plus" aria-hidden="true"></span>
-			Add a circuit
-		</a>
-        <a href="{% url 'circuits:circuit_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import circuits
-        </a>
+        {% add_button 'circuits:circuit_add' %}
+        {% import_button 'circuits:circuit_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='circuits' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Circuits{% endblock %}</h1>
 <div class="row">

+ 4 - 8
netbox/templates/circuits/circuittype_list.html

@@ -1,18 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.circuits.add_circuittype %}
-        <a href="{% url 'circuits:circuittype_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a circuit type
-        </a>
-        <a href="{% url 'circuits:circuittype_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import circuit types
-        </a>
+        {% add_button 'circuits:circuittype_add' %}
+        {% import_button 'circuits:circuittype_import' %}
     {% endif %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Circuit Types{% endblock %}</h1>
 <div class="row">

+ 4 - 9
netbox/templates/circuits/provider_list.html

@@ -1,18 +1,13 @@
 {% extends '_base.html' %}
+{% load buttons %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.circuits.add_provider %}
-		<a href="{% url 'circuits:provider_add' %}" class="btn btn-primary">
-			<span class="fa fa-plus" aria-hidden="true"></span>
-			Add a provider
-		</a>
-        <a href="{% url 'circuits:provider_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import providers
-        </a>
+        {% add_button 'circuits:provider_add' %}
+        {% import_button 'circuits:provider_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='providers' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Providers{% endblock %}</h1>
 <div class="row">

+ 3 - 5
netbox/templates/dcim/console_connections_list.html

@@ -1,14 +1,12 @@
 {% extends '_base.html' %}
+{% load buttons %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.dcim.change_consoleport %}
-        <a href="{% url 'dcim:console_connections_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import connections
-        </a>
+        {% import_button 'dcim:console_connections_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='connections' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Console Connections{% endblock %}</h1>
 <div class="row">

+ 4 - 9
netbox/templates/dcim/device_list.html

@@ -1,19 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.dcim.add_device %}
-        <a href="{% url 'dcim:device_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a device
-        </a>
-        <a href="{% url 'dcim:device_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import devices
-        </a>
+        {% add_button 'dcim:device_add' %}
+        {% import_button 'dcim:device_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='devices' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Devices{% endblock %}</h1>
 <div class="row">

+ 4 - 8
netbox/templates/dcim/devicerole_list.html

@@ -1,18 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.dcim.add_devicerole %}
-        <a href="{% url 'dcim:devicerole_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a device role
-        </a>
-        <a href="{% url 'dcim:devicerole_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import device roles
-        </a>
+        {% add_button 'dcim:devicerole_add' %}
+        {% import_button 'dcim:devicerole_import' %}
     {% endif %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Device Roles{% endblock %}</h1>
 <div class="row">

+ 4 - 9
netbox/templates/dcim/devicetype_list.html

@@ -1,19 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.dcim.add_devicetype %}
-        <a href="{% url 'dcim:devicetype_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a device type
-        </a>
-        <a href="{% url 'dcim:devicetype_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import device types
-        </a>
+        {% add_button 'dcim:devicetype_add' %}
+        {% import_button 'dcim:devicetype_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='device types' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Device Types{% endblock %}</h1>
 <div class="row">

+ 3 - 5
netbox/templates/dcim/interface_connections_list.html

@@ -1,14 +1,12 @@
 {% extends '_base.html' %}
+{% load buttons %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.dcim.add_interfaceconnection %}
-        <a href="{% url 'dcim:interface_connections_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import connections
-        </a>
+        {% import_button 'dcim:interface_connections_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='connections' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Interface Connections{% endblock %}</h1>
 <div class="row">

+ 3 - 5
netbox/templates/dcim/inventoryitem_list.html

@@ -1,15 +1,13 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.dcim.add_devicetype %}
-        <a href="{% url 'dcim:inventoryitem_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import inventory items
-        </a>
+        {% import_button 'dcim:inventoryitem_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='inventory items' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Inventory Items{% endblock %}</h1>
 <div class="row">

+ 4 - 9
netbox/templates/dcim/manufacturer_list.html

@@ -1,19 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.dcim.add_manufacturer %}
-        <a href="{% url 'dcim:manufacturer_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a manufacturer
-        </a>
-        <a href="{% url 'dcim:manufacturer_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import manufacturers
-        </a>
+        {% add_button 'dcim:manufacturer_add' %}
+        {% import_button 'dcim:manufacturer_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='manufacturers' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Manufacturers{% endblock %}</h1>
 <div class="row">

+ 4 - 8
netbox/templates/dcim/platform_list.html

@@ -1,18 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.dcim.add_platform %}
-        <a href="{% url 'dcim:platform_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a platform
-        </a>
-        <a href="{% url 'dcim:platform_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import platforms
-        </a>
+        {% add_button 'dcim:platform_add' %}
+        {% import_button 'dcim:platform_import' %}
     {% endif %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Platforms{% endblock %}</h1>
 <div class="row">

+ 3 - 5
netbox/templates/dcim/power_connections_list.html

@@ -1,14 +1,12 @@
 {% extends '_base.html' %}
+{% load buttons %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.dcim.change_powerport %}
-        <a href="{% url 'dcim:power_connections_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import connections
-        </a>
+        {% import_button 'dcim:power_connections_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='connections' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Power Connections{% endblock %}</h1>
 <div class="row">

+ 4 - 9
netbox/templates/dcim/rack_list.html

@@ -1,19 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.dcim.add_rack %}
-        <a href="{% url 'dcim:rack_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a rack
-        </a>
-        <a href="{% url 'dcim:rack_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import racks
-        </a>
+        {% add_button 'dcim:rack_add' %}
+        {% import_button 'dcim:rack_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='racks' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Racks{% endblock %}</h1>
 <div class="row">

+ 4 - 9
netbox/templates/dcim/rackgroup_list.html

@@ -1,19 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.dcim.add_rackgroup %}
-        <a href="{% url 'dcim:rackgroup_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a rack group
-        </a>
-        <a href="{% url 'dcim:rackgroup_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import rack groups
-        </a>
+        {% add_button 'dcim:rackgroup_add' %}
+        {% import_button 'dcim:rackgroup_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='rack groups' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Rack Groups{% endblock %}</h1>
 <div class="row">

+ 4 - 9
netbox/templates/dcim/region_list.html

@@ -1,19 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.dcim.add_region %}
-        <a href="{% url 'dcim:region_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a region
-        </a>
-        <a href="{% url 'dcim:region_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import regions
-        </a>
+        {% add_button 'dcim:region_add' %}
+        {% import_button 'dcim:region_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='regions' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Regions{% endblock %}</h1>
 <div class="row">

+ 4 - 9
netbox/templates/dcim/site_list.html

@@ -1,18 +1,13 @@
 {% extends '_base.html' %}
+{% load buttons %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.dcim.add_site %}
-		<a href="{% url 'dcim:site_add' %}" class="btn btn-primary">
-			<span class="fa fa-plus" aria-hidden="true"></span>
-			Add a site
-		</a>
-        <a href="{% url 'dcim:site_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import sites
-        </a>
+        {% add_button 'dcim:site_add' %}
+        {% import_button 'dcim:site_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='sites' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Sites{% endblock %}</h1>
 <div class="row">

+ 0 - 20
netbox/templates/inc/export_button.html

@@ -1,20 +0,0 @@
-{% if export_templates %}
-    <div class="btn-group">
-        <button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-            <span class="fa fa-upload" aria-hidden="true"></span>
-            Export {{ obj_type }} <span class="caret"></span>
-        </button>
-        <ul class="dropdown-menu">
-            <li><a href="?{% if request.GET %}{{ request.GET.urlencode }}&{% endif %}export">CSV (default)</a></li>
-            <li class="divider"></li>
-            {% for et in export_templates %}
-                <li><a href="?{% if request.GET %}{{ request.GET.urlencode }}&{% endif %}export={{ et.name }}"{% if et.description %} title="{{ et.description }}"{% endif %}>{{ et.name }}</a></li>
-            {% endfor %}
-        </ul>
-    </div>
-{% else %}
-    <a href="?{% if request.GET %}{{ request.GET.urlencode }}&{% endif %}export" class="btn btn-success">
-        <span class="fa fa-upload" aria-hidden="true"></span>
-        Export {{ obj_type }}
-    </a>
-{% endif %}

+ 4 - 9
netbox/templates/ipam/aggregate_list.html

@@ -1,20 +1,15 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load humanize %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.ipam.add_aggregate %}
-		<a href="{% url 'ipam:aggregate_add' %}" class="btn btn-primary">
-			<span class="fa fa-plus" aria-hidden="true"></span>
-			Add an aggregate
-		</a>
-        <a href="{% url 'ipam:aggregate_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import aggregates
-        </a>
+        {% add_button 'ipam:aggregate_add' %}
+        {% import_button 'ipam:aggregate_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='aggregates' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Aggregates{% endblock %}</h1>
 <div class="row">

+ 5 - 10
netbox/templates/ipam/ipaddress_list.html

@@ -1,19 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.ipam.add_ipaddress %}
-		<a href="{% url 'ipam:ipaddress_add' %}" class="btn btn-primary">
-			<span class="fa fa-plus" aria-hidden="true"></span>
-			Add an IP
-		</a>
-		<a href="{% url 'ipam:ipaddress_import' %}" class="btn btn-info">
-			<span class="fa fa-download" aria-hidden="true"></span>
-			Import IPs
-		</a>
-	{% endif %}
-    {% include 'inc/export_button.html' with obj_type='IPs' %}
+        {% add_button 'ipam:ipaddress_add' %}
+        {% import_button 'ipam:ipaddress_import' %}
+    {% endif %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}IP Addresses{% endblock %}</h1>
 <div class="row">

+ 5 - 10
netbox/templates/ipam/prefix_list.html

@@ -1,4 +1,5 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 {% load form_helpers %}
 
@@ -9,16 +10,10 @@
         <a href="{% url 'ipam:prefix_list' %}{% querystring request expand='on' page=1 %}" class="btn btn-default{% if request.GET.expand %} active{% endif %}">Expand</a>
     </div>
     {% if perms.ipam.add_prefix %}
-		<a href="{% url 'ipam:prefix_add' %}" class="btn btn-primary">
-			<span class="fa fa-plus" aria-hidden="true"></span>
-			Add a prefix
-		</a>
-		<a href="{% url 'ipam:prefix_import' %}" class="btn btn-info">
-			<span class="fa fa-download" aria-hidden="true"></span>
-			Import prefixes
-		</a>
-	{% endif %}
-    {% include 'inc/export_button.html' with obj_type='prefixes' %}
+        {% add_button 'ipam:prefix_add' %}
+        {% import_button 'ipam:prefix_import' %}
+    {% endif %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Prefixes{% endblock %}</h1>
 <div class="row">

+ 4 - 8
netbox/templates/ipam/rir_list.html

@@ -1,4 +1,5 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load humanize %}
 {% load helpers %}
 
@@ -16,15 +17,10 @@
         </a>
     {% endif %}
     {% if perms.ipam.add_rir %}
-        <a href="{% url 'ipam:rir_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a RIR
-        </a>
-        <a href="{% url 'ipam:rir_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import RIRs
-        </a>
+        {% add_button 'ipam:rir_add' %}
+        {% import_button 'ipam:rir_import' %}
     {% endif %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}RIRs{% endblock %}</h1>
 <div class="row">

+ 4 - 8
netbox/templates/ipam/role_list.html

@@ -1,18 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.ipam.add_role %}
-        <a href="{% url 'ipam:role_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a role
-        </a>
-        <a href="{% url 'ipam:role_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import roles
-        </a>
+        {% add_button 'ipam:role_add' %}
+        {% import_button 'ipam:role_import' %}
     {% endif %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Prefix/VLAN Roles{% endblock %}</h1>
 <div class="row">

+ 5 - 10
netbox/templates/ipam/vlan_list.html

@@ -1,20 +1,15 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 {% load form_helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.ipam.add_vlan %}
-		<a href="{% url 'ipam:vlan_add' %}" class="btn btn-primary">
-			<span class="fa fa-plus" aria-hidden="true"></span>
-			Add a VLAN
-		</a>
-		<a href="{% url 'ipam:vlan_import' %}" class="btn btn-info">
-			<span class="fa fa-download" aria-hidden="true"></span>
-			Import VLANs
-		</a>
-	{% endif %}
-    {% include 'inc/export_button.html' with obj_type='VLANs' %}
+        {% add_button 'ipam:vlan_add' %}
+        {% import_button 'ipam:vlan_import' %}
+    {% endif %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}VLANs{% endblock %}</h1>
 <div class="row">

+ 4 - 8
netbox/templates/ipam/vlangroup_list.html

@@ -1,18 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.ipam.add_vlangroup %}
-        <a href="{% url 'ipam:vlangroup_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a VLAN group
-        </a>
-        <a href="{% url 'ipam:vlangroup_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import VLAN groups
-        </a>
+        {% add_button 'ipam:vlangroup_add' %}
+        {% import_button 'ipam:vlangroup_import' %}
     {% endif %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}VLAN Groups{% endblock %}</h1>
 <div class="row">

+ 4 - 10
netbox/templates/ipam/vrf_list.html

@@ -5,16 +5,10 @@
 {% block content %}
 <div class="pull-right">
     {% if perms.ipam.add_vrf %}
-		<a href="{% url 'ipam:vrf_add' %}" class="btn btn-primary">
-			<span class="fa fa-plus" aria-hidden="true"></span>
-			Add a VRF
-		</a>
-		<a href="{% url 'ipam:vrf_import' %}" class="btn btn-info">
-			<span class="fa fa-download" aria-hidden="true"></span>
-			Import VRFs
-		</a>
-	{% endif %}
-    {% include 'inc/export_button.html' with obj_type='VRFs' %}
+        {% add_button 'ipam:vrf_add' %}
+        {% import_button 'ipam:vrf_import' %}
+    {% endif %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}VRFs{% endblock %}</h1>
 <div class="row">

+ 2 - 4
netbox/templates/secrets/secret_list.html

@@ -1,13 +1,11 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.secrets.add_secret %}
-        <a href="{% url 'secrets:secret_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import secrets
-        </a>
+        {% import_button 'secrets:secret_import' %}
     {% endif %}
 </div>
 <h1>{% block title %}Secrets{% endblock %}</h1>

+ 5 - 9
netbox/templates/secrets/secretrole_list.html

@@ -1,18 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
-    {% if perms.dcim.add_devicerole %}
-        <a href="{% url 'secrets:secretrole_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a secret role
-        </a>
-        <a href="{% url 'secrets:secretrole_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import secret roles
-        </a>
+    {% if perms.secrets.add_secretrole %}
+        {% add_button 'secrets:secretrole_add' %}
+        {% import_button 'secrets:secretrole_import' %}
     {% endif %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Secret Roles{% endblock %}</h1>
 <div class="row">

+ 4 - 9
netbox/templates/tenancy/tenant_list.html

@@ -1,19 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.tenancy.add_tenant %}
-		<a href="{% url 'tenancy:tenant_add' %}" class="btn btn-primary">
-			<span class="fa fa-plus" aria-hidden="true"></span>
-			Add a tenant
-		</a>
-        <a href="{% url 'tenancy:tenant_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import tenants
-        </a>
+        {% add_button 'tenancy:tenant_add' %}
+        {% import_button 'tenancy:tenant_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='tenants' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Tenants{% endblock %}</h1>
 <div class="row">

+ 4 - 8
netbox/templates/tenancy/tenantgroup_list.html

@@ -1,18 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.tenancy.add_tenantgroup %}
-        <a href="{% url 'tenancy:tenantgroup_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a tenant group
-        </a>
-        <a href="{% url 'tenancy:tenantgroup_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import tenant groups
-        </a>
+        {% add_button 'tenancy:tenantgroup_add' %}
+        {% import_button 'tenancy:tenantgroup_import' %}
     {% endif %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Tenant Groups{% endblock %}</h1>
 <div class="row">

+ 4 - 9
netbox/templates/virtualization/cluster_list.html

@@ -1,18 +1,13 @@
 {% extends '_base.html' %}
+{% load buttons %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.virtualization.add_cluster %}
-		<a href="{% url 'virtualization:cluster_add' %}" class="btn btn-primary">
-			<span class="fa fa-plus" aria-hidden="true"></span>
-			Add a cluster
-		</a>
-        <a href="{% url 'virtualization:cluster_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import clusters
-        </a>
+        {% add_button 'virtualization:cluster_add' %}
+        {% import_button 'virtualization:cluster_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='clusters' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Clusters{% endblock %}</h1>
 <div class="row">

+ 4 - 8
netbox/templates/virtualization/clustergroup_list.html

@@ -1,18 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.virtualization.add_clustergroup %}
-        <a href="{% url 'virtualization:clustergroup_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a cluster group
-        </a>
-        <a href="{% url 'virtualization:clustergroup_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import cluster groups
-        </a>
+        {% add_button 'virtualization:clustergroup_add' %}
+        {% import_button 'virtualization:clustergroup_import' %}
     {% endif %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Cluster Groups{% endblock %}</h1>
 <div class="row">

+ 4 - 8
netbox/templates/virtualization/clustertype_list.html

@@ -1,18 +1,14 @@
 {% extends '_base.html' %}
+{% load buttons %}
 {% load helpers %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.virtualization.add_clustertype %}
-        <a href="{% url 'virtualization:clustertype_add' %}" class="btn btn-primary">
-            <span class="fa fa-plus" aria-hidden="true"></span>
-            Add a cluster type
-        </a>
-        <a href="{% url 'virtualization:clustertype_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import cluster types
-        </a>
+        {% add_button 'virtualization:clustertype_add' %}
+        {% import_button 'virtualization:clustertype_import' %}
     {% endif %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Cluster Types{% endblock %}</h1>
 <div class="row">

+ 4 - 9
netbox/templates/virtualization/virtualmachine_list.html

@@ -1,18 +1,13 @@
 {% extends '_base.html' %}
+{% load buttons %}
 
 {% block content %}
 <div class="pull-right">
     {% if perms.virtualization.add_virtualmachine %}
-		<a href="{% url 'virtualization:virtualmachine_add' %}" class="btn btn-primary">
-			<span class="fa fa-plus" aria-hidden="true"></span>
-			Add a virtual machine
-		</a>
-        <a href="{% url 'virtualization:virtualmachine_import' %}" class="btn btn-info">
-            <span class="fa fa-download" aria-hidden="true"></span>
-            Import virtual machines
-        </a>
+        {% add_button 'virtualization:virtualmachine_add' %}
+        {% import_button 'virtualization:virtualmachine_import' %}
     {% endif %}
-    {% include 'inc/export_button.html' with obj_type='virtual machines' %}
+    {% export_button content_type %}
 </div>
 <h1>{% block title %}Virtual Machines{% endblock %}</h1>
 <div class="row">

+ 3 - 0
netbox/utilities/templates/buttons/add.html

@@ -0,0 +1,3 @@
+<a href="{% url add_url %}" class="btn btn-primary">
+    <span class="fa fa-plus" aria-hidden="true"></span> Add
+</a>

+ 19 - 0
netbox/utilities/templates/buttons/export.html

@@ -0,0 +1,19 @@
+{% if export_templates %}
+    <div class="btn-group">
+        <button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+            <span class="fa fa-upload" aria-hidden="true"></span>
+            Export <span class="caret"></span>
+        </button>
+        <ul class="dropdown-menu">
+            <li><a href="?{% if url_params %}{{ url_params.urlencode }}&{% endif %}export">CSV (default)</a></li>
+            <li class="divider"></li>
+            {% for et in export_templates %}
+                <li><a href="?{% if url_params %}{{ url_params.urlencode }}&{% endif %}export={{ et.name }}"{% if et.description %} title="{{ et.description }}"{% endif %}>{{ et.name }}</a></li>
+            {% endfor %}
+        </ul>
+    </div>
+{% else %}
+    <a href="?{% if url_params %}{{ url_params.urlencode }}&{% endif %}export" class="btn btn-success">
+        <span class="fa fa-upload" aria-hidden="true"></span> Export
+    </a>
+{% endif %}

+ 3 - 0
netbox/utilities/templates/buttons/import.html

@@ -0,0 +1,3 @@
+<a href="{% url import_url %}" class="btn btn-info">
+    <span class="fa fa-download" aria-hidden="true"></span> Import
+</a>

+ 26 - 0
netbox/utilities/templatetags/buttons.py

@@ -0,0 +1,26 @@
+from __future__ import unicode_literals
+
+from django import template
+
+from extras.models import ExportTemplate
+
+register = template.Library()
+
+
+@register.inclusion_tag('buttons/add.html')
+def add_button(url):
+    return {'add_url': url}
+
+
+@register.inclusion_tag('buttons/import.html')
+def import_button(url):
+    return {'import_url': url}
+
+
+@register.inclusion_tag('buttons/export.html', takes_context=True)
+def export_button(context, content_type=None):
+    export_templates = ExportTemplate.objects.filter(content_type=content_type)
+    return {
+        'url_params': context['request'].GET,
+        'export_templates': export_templates,
+    }

+ 3 - 3
netbox/utilities/views.py

@@ -79,7 +79,7 @@ class ObjectListView(View):
     def get(self, request):
 
         model = self.queryset.model
-        object_ct = ContentType.objects.get_for_model(model)
+        content_type = ContentType.objects.get_for_model(model)
 
         if self.filter:
             self.queryset = self.filter(request.GET, self.queryset).qs
@@ -92,7 +92,7 @@ class ObjectListView(View):
 
         # Check for export template rendering
         if request.GET.get('export'):
-            et = get_object_or_404(ExportTemplate, content_type=object_ct, name=request.GET.get('export'))
+            et = get_object_or_404(ExportTemplate, content_type=content_type, name=request.GET.get('export'))
             queryset = CustomFieldQueryset(self.queryset, custom_fields) if custom_fields else self.queryset
             try:
                 return et.render_to_response(queryset)
@@ -125,10 +125,10 @@ class ObjectListView(View):
         RequestConfig(request, paginate).configure(table)
 
         context = {
+            'content_type': content_type,
             'table': table,
             'permissions': permissions,
             'filter_form': self.filter_form(request.GET, label_suffix='') if self.filter_form else None,
-            'export_templates': ExportTemplate.objects.filter(content_type=object_ct),
         }
         context.update(self.extra_context())