### Basic NodeGraphQt Setup Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_overview.rst This example demonstrates how to create a basic NodeGraphQt application, register a custom node class, create instances of that node, and connect them. ```python from Qt import QtWidgets from NodeGraphQt import NodeGraph, BaseNode # create a node class object inherited from BaseNode. class FooNode(BaseNode): # unique node identifier domain. __identifier__ = 'io.github.jchanvfx' # initial default node name. NODE_NAME = 'Foo Node' def __init__(self): super(FooNode, self).__init__() # create an input port. self.add_input('in', color=(180, 80, 0)) # create an output port. self.add_output('out') if __name__ == '__main__': app = QtWidgets.QApplication([]) # create node graph controller. graph = NodeGraph() # register the FooNode node class. graph.register_node(FooNode) # show the node graph widget. graph_widget = graph.widget graph_widget.show() # create two nodes. node_a = graph.create_node('io.github.jchanvfx.FooNode', name='node A') node_b = graph.create_node('io.github.jchanvfx.FooNode', name='node B', pos=(300, 50)) # connect node_a to node_b node_a.set_output(0, node_b.input(0)) app.exec_() ``` -------------------------------- ### Example Python Script for Commands Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_menu.rst Python script containing functions to be triggered by context menu commands. ```python def graph_command(graph): """ function that's triggered on the node graph context menu. Args: graph (NodeGraphQt.NodeGraph): node graph controller. """ print(graph) def node_command(graph, node): """ function that's triggered on a node's node context menu. Args: graph (NodeGraphQt.NodeGraph): node graph controller. node: (NodeGraphQt.NodeObject): node object triggered on. """ print(graph) print(node.name()) ``` -------------------------------- ### Example Connection Constraints Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_port.rst An example snippet demonstrating how to add pipe connection constraints to a port using NodeGraphQt. ```python from NodeGraphQt import BaseNode from NodeGraphQt.constants import PortTypeEnum class BasicNodeA(BaseNode): ``` -------------------------------- ### Setting Context Menu from JSON Files Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_menu.rst This example demonstrates how to load context menu configurations from JSON files for both the graph and nodes. ```python from NodeGraphQt import NodeGraph node_graph = NodeGraph() node_graph.set_context_menu_from_file( '../path/to/a/hotkeys/graph_commands.json', menu='graph' ) node_graph.set_context_menu_from_file( '../path/to/a/hotkeys/node_commands.json', menu='nodes' ) ``` -------------------------------- ### Install NodeGraphQt Source: https://github.com/jchanvfx/nodegraphqt/blob/main/README.md NodeGraphQt can be installed using pip from the Python Package Index (PyPI). ```bash pip install NodeGraphQt ``` -------------------------------- ### Adding to the Graph Menu Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_menu.rst Example of adding a custom menu and command to the main graph context menu. ```python from NodeGraphQt import NodeGraph # test function. def my_test(graph): selected_nodes = graph.selected_nodes() print('Number of nodes selected: {}'.format(len(selected_nodes))) # create node graph. node_graph = NodeGraph() # get the main context menu. context_menu = node_graph.get_context_menu('graph') # add a menu called "Foo". foo_menu = context_menu.add_menu('Foo') # add "Bar" command to the "Foo" menu. # we also assign a short cut key "Shift+t" for this example. foo_menu.add_command('Bar', my_test, 'Shift+t') ``` -------------------------------- ### Adding to the Nodes Menu Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_menu.rst Example of overriding context menus for specific node types. ```python from NodeGraphQt import BaseNode, NodeGraph # define a couple example nodes. class FooNode(BaseNode): __identifier__ = 'io.github.jchanvfx' NODE_NAME = 'foo node' def __init__(self): super(FooNode, self).__init__() self.add_input('in') self.add_output('out') class BarNode(FooNode): NODE_NAME = 'bar node' # define a test function. def test_func(graph, node): print('Clicked on node: {}'.format(node.name())) # create node graph and register node classes. node_graph = NodeGraph() node_graph.register_node(FooNode) node_graph.register_node(BarNode) # get the nodes menu. nodes_menu = node_graph.get_context_menu('nodes') # here we add override the context menu for "io.github.jchanvfx.FooNode". nodes_menu.add_command('Test', func=test_func, node_type='io.github.jchanvfx.FooNode') # create some nodes. foo_node = graph.create_node('io.github.jchanvfx.FooNode') bar_node = graph.create_node('io.github.jchanvfx', pos=(300, 100)) # show widget. node_graph.widget.show() ``` -------------------------------- ### Basic Node A Example Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_port.rst Defines a basic node with two output ports. ```Python # unique node identifier. __identifier__ = 'io.github.jchanvfx' # initial default node name. NODE_NAME = 'node A' def __init__(self): super(BasicNode, self).__init__() # create node output ports. self.add_output('output 1') self.add_output('output 2') ``` -------------------------------- ### Creating a Node Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_node.rst Demonstrates how to define a custom node class and create instances of it within a NodeGraph. ```python from Qt import QtWidgets from NodeGraphQt import BaseNode, NodeGraph class MyNode(BaseNode): __identifier__ = 'io.github.jchanvfx' NODE_NAME = 'my node' def __init__(self): super(MyNode, self).__init__() self.add_input('foo') self.add_input('hello') self.add_output('bar') self.add_output('world') if __name__ == '__main__': app = QtWidgets.QApplication([]) node_graph = NodeGraph() node_graph.register_node(MyNode) node_graph.widget.show() # here we create a couple nodes in the node graph. node_a = node_graph.create_node('io.github.jchanvfx.MyNode', name='node a') node_b = node_graph.create_node('io.github.jchanvfx.MyNode', name='node b', pos=(300, 100)) app.exec_() ``` -------------------------------- ### Example JSON Config for Graph Context Menu Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_menu.rst JSON configuration for adding menus and commands to the node graph context menu. ```json [ { "type":"menu", "label":"My Sub Menu", "items":[ { "type":"command", "label":"Example Graph Command", "file":"../examples/hotkeys/cmd_functions.py", "function_name":"graph_command", "shortcut":"Shift+t", } ] } ] ``` -------------------------------- ### Example JSON Config for Nodes Context Menu Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_menu.rst JSON configuration for adding commands to the nodes context menu, specific to node types. ```json [ { "type":"command", "label":"Example Graph Command", "file":"../examples/hotkeys/cmd_functions.py", "function_name":"node_command", "node_type":"io.github.jchanvfx.FooNode", } ] ``` -------------------------------- ### Silhouette Node Graph Example Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/host_apps/ex_app_silhouette.rst Example of creating a node graph widget and registering it as a dockable panel in Silhouette FX. ```python import fx from Qt import QtWidgets, QtCore from NodeGraphQt import NodeGraph, BaseNode # create the widget wrapper that can be docked to the main window. class NodeGraphPanel(QtWidgets.QDockWidget): """ Widget wrapper for the node graph that can be docked to the main window. """ def __init__(self, graph, parent=None): super(NodeGraphPanel, self).__init__(parent) self.setObjectName('nodeGraphQt.NodeGraphPanel') self.setWindowTitle('Custom Node Graph') self.setWidget(graph.widget) # create a simple test node class. class TestNode(BaseNode): __identifier__ = 'nodes.silhouettefx' NODE_NAME = 'test node' def __init__(self): super(TestNode, self).__init__() self.add_input('in') self.add_output('out') # create the node graph controller and register our "TestNode" graph = NodeGraph() graph.register_node(TestNode) # create nodes. node_1 = graph.create_node('nodes.silhouette.TestNode') node_2 = graph.create_node('nodes.silhouette.TestNode') node_3 = graph.create_node('nodes.silhouette.TestNode') # create the node graph panel that can be docked. sfx_graph_panel = NodeGraphPanel(graph) # add the doc widget into the main silhouette window. sfx_window = fx.ui.mainWindow() sfx_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, sfx_graph_panel) ``` -------------------------------- ### Setting Context Menu with Serialized Data Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_menu.rst This example shows how to define and set context menus using a Python list of dictionaries, providing an alternative to JSON configuration files. ```python from NodeGraphQt import NodeGraph data = [ { 'type': 'menu', 'label': 'My Sub Menu', 'items': [ { 'type': 'command', 'label': 'Example Graph Command', 'file': '../examples/hotkeys/cmd_functions.py', 'function_name': 'graph_command', 'shortcut': 'Shift+t' }, ] }, ] node_graph = NodeGraph() node_graph.set_context_menu(menu_name='graph', data) ``` -------------------------------- ### Connecting Nodes by Port Name Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_node.rst Shows how to connect nodes using the names of their input and output ports. ```python node_a.outputs()['bar'].connect_to(node_b.inputs()['foo']) ``` -------------------------------- ### Connecting Nodes by Port Index Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_node.rst Demonstrates how to connect two nodes by specifying the index of their input and output ports. ```python node_b.set_input(0, node_a.output(0)) ``` -------------------------------- ### Node Definition Example Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_node.rst Defines a custom node class 'MyNode' inheriting from BaseNode, including input/output ports and a custom widget. ```python class MyNode(BaseNode): """ Example node. """ # set a unique node identifier. __identifier__ = 'io.github.jchanvfx' # set the initial default node name. NODE_NAME = 'my node' def __init__(self): super(MyNode, self).__init__() # create input and output port. self.add_input('in') self.add_output('out') # add custom widget to node with "node.view" as the parent. node_widget = NodeWidgetWrapper(self.view) self.add_custom_widget(node_widget, tab='Custom') ``` -------------------------------- ### Basic Node B Example Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_port.rst Defines a basic node with input ports that accept or reject specific connections. ```Python class BasicNodeB(BaseNode): # unique node identifier. __identifier__ = 'io.github.jchanvfx' # initial default node name. NODE_NAME = 'node B' def __init__(self): super(BasicNode, self).__init__() # create node inputs. # port "in A" will only accept pipe connections from port "output 1" # under the node "BasicNodeA". in_port_a = self.add_input('in A') in_port_a.add_accept_port_type( port_name='output 1', port_type=PortTypeEnum.OUT.value, node_type='io.github.jchanvfx.BasicNodeA' ) # port "in A" will reject pipe connections from port "output 1" # under the node "BasicNodeA". in_port_b = self.add_input('in B') in_port_b.add_reject_port_type( port_name='output 1', port_type=PortTypeEnum.OUT.value, node_type='io.github.jchanvfx.BasicNodeA' ) ``` -------------------------------- ### Connecting Nodes with Port Objects Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_node.rst Illustrates connecting nodes by obtaining port objects first and then using the connect_to method. ```python # node_a "bar" output port. port_a = node_a.output(0) # node_b "foo" input port. port_b = node_b.inputs()['foo'] # make the connection. port_a.connect_to(port_b) ``` -------------------------------- ### Embedding a Custom Widget Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_node.rst Illustrates embedding a fully custom QtWidgets.QWidget into a node by subclassing NodeBaseWidget. ```python from Qt import QtCore, QtWidgets from NodeGraphQt import BaseNode, NodeBaseWidget class MyCustomWidget(QtWidgets.QWidget): """ Custom widget to be embedded inside a node. """ def __init__(self, parent=None): super(MyCustomWidget, self).__init__(parent) self.combo_1 = QtWidgets.QComboBox() self.combo_1.addItems(['a', 'b', 'c']) self.combo_2 = QtWidgets.QComboBox() self.combo_2.addItems(['a', 'b', 'c']) self.btn_go = QtWidgets.QPushButton('Go') layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.combo_1) layout.addWidget(self.combo_2) layout.addWidget(self.btn_go) class NodeWidgetWrapper(NodeBaseWidget): """ Wrapper that allows the widget to be added in a node object. """ def __init__(self, parent=None): super(NodeWidgetWrapper, self).__init__(parent) # set the name for node property. self.set_name('my_widget') # set the label above the widget. self.set_label('Custom Widget') # set the custom widget. self.set_custom_widget(MyCustomWidget()) # connect up the signals & slots. self.wire_signals() def wire_signals(self): widget = self.get_custom_widget() # wire up the combo boxes. widget.combo_1.currentIndexChanged.connect(self.on_value_changed) widget.combo_2.currentIndexChanged.connect(self.on_value_changed) # wire up the button. widget.btn_go.clicked.connect(self.on_btn_go_clicked) def on_btn_go_clicked(self): print('Clicked on node: "{}"'.format(self.node.name())) def get_value(self): widget = self.get_custom_widget() return '{}/{}'.format(widget.combo_1.currentText(), widget.combo_2.currentText()) def set_value(self, value): value = value.split('/') if len(value) < 2: combo1_val = value[0] combo2_val = '' else: combo1_val, combo2_val = value widget = self.get_custom_widget() cb1_index = widget.combo_1.findText(combo1_val, QtCore.Qt.MatchExactly) ``` -------------------------------- ### Custom NodeGraph with PropertiesBinWidget Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_node.rst Subclasses NodeGraph to integrate a PropertiesBinWidget, which is shown when a node is double-clicked. ```python from Qt import QtCore, QtWidgets from NodeGraphQt import BaseNode, NodeGraph, PropertiesBinWidget class MyNode(BaseNode): __identifier__ = 'io.github.jchanvfx' NODE_NAME = 'my node' def __init__(self): super(MyNode, self).__init__() self.add_input('in') self.add_output('out') class MyNodeGraph(NodeGraph): def __init__(self, parent=None): super(MyNodeGraph, self).__init__(parent) # properties bin widget. self._prop_bin = PropertiesBinWidget(node_graph=self) self._prop_bin.setWindowFlags(QtCore.Qt.Tool) # wire signal. self.node_double_clicked.connect(self.display_prop_bin) def display_prop_bin(self, node): """ function for displaying the properties bin when a node is double clicked """ if not self._prop_bin.isVisible(): self._prop_bin.show() if __name__ == '__main__': app = QtWidgets.QApplication([]) node_graph = MyNodeGraph() node_graph.register_node(MyNode) node_graph.widget.show() node_a = node_graph.create_node('io.github.jchanvfx.MyNode') app.exec_() ``` -------------------------------- ### Adding a Triangle Port to a Node Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_port.rst Example of how to add a custom triangle port to a NodeGraphQt BaseNode by passing the draw_triangle_port function to the painter_func argument of add_input. ```python from NodeGraphQt import BaseNode class MyListNode(BaseNode): def __init__(self): super(MyListNode, self).__init__() # create a input port with custom painter function. self.add_input('triangle', painter_func=draw_triangle_port) ``` -------------------------------- ### Example Triangle Port Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_port.rst A custom paint function for drawing a Triangle shaped port. It takes painter, rect, and info arguments and draws a triangle based on the port's state (hovered, connected, default). ```python def draw_triangle_port(painter, rect, info): """ Custom paint function for drawing a Triangle shaped port. Args: painter (QtGui.QPainter): painter object. rect (QtCore.QRectF): port rect used to describe parameters needed to draw. info (dict): information describing the ports current state. { 'port_type': 'in', 'color': (0, 0, 0), 'border_color': (255, 255, 255), 'multi_connection': False, 'connected': False, 'hovered': False, } """ painter.save() # create triangle polygon. size = int(rect.height() / 2) triangle = QtGui.QPolygonF() triangle.append(QtCore.QPointF(-size, size)) triangle.append(QtCore.QPointF(0.0, -size)) triangle.append(QtCore.QPointF(size, size)) # map polygon to port position. transform = QtGui.QTransform() transform.translate(rect.center().x(), rect.center().y()) port_poly = transform.map(triangle) # mouse over port color. if info['hovered']: color = QtGui.QColor(14, 45, 59) border_color = QtGui.QColor(136, 255, 35) # port connected color. elif info['connected']: color = QtGui.QColor(195, 60, 60) border_color = QtGui.QColor(200, 130, 70) # default port color else: color = QtGui.QColor(*info['color']) border_color = QtGui.QColor(*info['border_color']) pen = QtGui.QPen(border_color, 1.8) pen.setJoinStyle(QtCore.Qt.MiterJoin) painter.setPen(pen) painter.setBrush(color) painter.drawPolygon(port_poly) painter.restore() ``` -------------------------------- ### NodeGraph Example Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/graphs/NodeGraph.rst This code snippet demonstrates how to create and display a NodeGraph widget. ```python from Qt import QtWidgets from NodeGraphQt import NodeGraph if __name__ == '__main__': app = QtWidgets.QApplication([]) node_graph = NodeGraph() widget = node_graph.widget widget.show() app.exec_() ``` -------------------------------- ### Example Square Port Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_port.rst A custom paint function for drawing a Square shaped port. Similar to the triangle port, it uses painter, rect, and info to draw a square based on the port's state. ```python def draw_square_port(painter, rect, info): """ Custom paint function for drawing a Square shaped port. Args: painter (QtGui.QPainter): painter object. rect (QtCore.QRectF): port rect used to describe parameters needed to draw. info (dict): information describing the ports current state. { 'port_type': 'in', 'color': (0, 0, 0), 'border_color': (255, 255, 255), 'multi_connection': False, 'connected': False, 'hovered': False, } """ painter.save() # mouse over port color. if info['hovered']: color = QtGui.QColor(14, 45, 59) border_color = QtGui.QColor(136, 255, 35, 255) # port connected color. elif info['connected']: color = QtGui.QColor(195, 60, 60) border_color = QtGui.QColor(200, 130, 70) # default port color else: color = QtGui.QColor(*info['color']) border_color = QtGui.QColor(*info['border_color']) pen = QtGui.QPen(border_color, 1.8) pen.setJoinStyle(QtCore.Qt.MiterJoin) painter.setPen(pen) painter.setBrush(color) painter.drawRect(rect) painter.restore() ``` -------------------------------- ### Embedding a QComboBox Widget Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_node.rst Shows how to embed a QComboBox widget directly into a custom node by reimplementing BaseNode. ```python from NodeGraphQt import BaseNode class MyListNode(BaseNode): __identifier__ = 'io.github.jchanvfx' NODE_NAME = 'node' def __init__(self): super(MyListNode, self).__init__() items = ['apples', 'bananas', 'pears', 'mangos', 'oranges'] self.add_combo_menu('my_list', 'My List', items) ``` -------------------------------- ### Updating an Embedded Widget Property Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_node.rst Demonstrates how to update the value of an embedded widget (like a QComboBox) using set_property. ```python node = MyListNode() node.set_property('my_list', 'mangos') ``` -------------------------------- ### Nuke Panel Registration Example Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/host_apps/ex_app_nuke.rst This code snippet shows how to create a NodeGraphQt instance, register a custom node, create nodes, connect them, and then register the NodeGraph widget as a panel within Nuke using nukescripts.panels.registerWidgetAsPanel. It also includes a workaround for setting zero margins in Nuke panels. ```python from nukescripts import panels from Qt import QtWidgets, QtCore from NodeGraphQt import NodeGraph, BaseNode # create a simple test node class. class TestNode(BaseNode): __identifier__ = 'nodes.nuke' NODE_NAME = 'test node' def __init__(self): super(TestNode, self).__init__() self.add_input('in') self.add_output('out 1') self.add_output('out 2') # create the node graph controller and register our "TestNode". graph = NodeGraph() graph.register_node(TestNode) # create nodes. node_1 = graph.create_node('nodes.nuke.TestNode') node_2 = graph.create_node('nodes.nuke.TestNode') node_3 = graph.create_node('nodes.nuke.TestNode') # connect the nodes. node_1.set_output(0, node_2.input(0)) node_2.set_output(1, node_3.input(0)) # auto layout the nodes. graph.auto_layout_nodes() # create a backdrop node and wrap it to node_1 and node_2. b backdrop = graph.create_node('Backdrop') bbackdrop.wrap_nodes([node_1, node_2]) # create the wrapper widget. class CustomNodeGraph(QtWidgets.QWidget): def __init__(self, parent=None): super(CustomNodeGraph, self).__init__(parent) layout = QtWidgets.QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(graph.widget) @staticmethod def _set_nuke_zero_margin(widget_object): """ Foundry Nuke hack for "nukescripts.panels.registerWidgetAsPanel" to remove the widget contents margin. sourced from: https://gist.github.com/maty974/4739917 Args: widget_object (QtWidgets.QWidget): widget object. """ if widget_object: parent_widget = widget_object.parentWidget().parentWidget() target_widgets = set() target_widgets.add(parent_widget) target_widgets.add(parent_widget.parentWidget().parentWidget()) for widget_layout in target_widgets: widget_layout.layout().setContentsMargins(0, 0, 0, 0) def event(self, event): if event.type() == QtCore.QEvent.Type.Show: try: self._set_nuke_zero_margin(self) except Exception: pass return super(CustomNodeGraph, self).event(event) # register the wrapper widget as a panel in Nuke. panels.registerWidgetAsPanel( widget='CustomNodeGraph', name='Custom Node Graph', id='nodegraphqt.graph.CustomNodeGraph' ) ``` -------------------------------- ### Set Pipe Style to Angled Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/examples/ex_pipe.rst This snippet shows how to set the pipe layout style to 'angled' using the NodeGraphQt library. ```python from NodeGraphQt import NodeGraph from NodeGraphQt.constants import PipeLayoutEnum graph = NodeGraph() graph.set_pipe_style(PipeLayoutEnum.ANGLE.value) ``` -------------------------------- ### Previous/Next Link Templates Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/prev_next.html Jinja templates for generating links to the previous and next pages in a documentation set. ```html {#- Templates for previous/next links. -#} {%- if prev %} [{{ prev.title|striptags|e }}]({{ prev.link|e }}) {%- endif %} {%- if next %} [{{ next.title|striptags|e }}]({{ next.link|e }}) {%- endif %} ``` -------------------------------- ### Main Page Wrapper Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/layout.html HTML structure for the main page wrapper, including a skip to content link. ```html Skip to content ``` -------------------------------- ### Script Macro Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/layout.html A Jinja macro to include JavaScript files and potentially a search script. ```html {%- macro script() %} {%- for js in script_files %} {{ js_tag(js) }} {%- endfor %} {%- if docsearch %} {#- Add docsearch script here if needed -#} {%- endif %} {%- endmacro -%} ``` -------------------------------- ### Search Box Template Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/searchbox.html Jinja2 template for the search box, displaying '⌘ K' as a shortcut if docsearch is not enabled. ```html {#- Template for the search box in the header. -#} {%- if docsearch %} {%- else %} ⌘ K {%- endif -%} ``` -------------------------------- ### Dark Mode Initialization Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/layout.html JavaScript code to initialize dark mode based on user preference or system settings, and store the preference in local storage. ```javascript const userPreference = localStorage.getItem('darkMode'); let mode; if (userPreference === 'dark' || window.matchMedia('(prefers-color-scheme: dark)').matches) { mode = 'dark'; document.documentElement.classList.add('dark'); } else { mode = 'light'; } if (!userPreference) { localStorage.setItem('darkMode', mode); } ``` -------------------------------- ### Favicon URL Logic Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/layout.html Jinja logic to determine the URL for the favicon, falling back to a default path if not explicitly provided. ```html {%- set _favicon_url = favicon_url | default(pathto('_static/' + (favicon or ""), 1)) -%} ``` -------------------------------- ### Conditional Sidebar Inclusion Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/layout.html Jinja logic to conditionally include the sidebar based on the presence of sidebar files. ```html {%- if sidebars|length > 0 -%} {#- Include sidebar.html if sidebars exist -#} {%- include "sidebar.html" %} {%- endif -%} ``` -------------------------------- ### Footer Template Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/footer.html Jinja2 template for generating the footer content, including copyright, last updated date, and Sphinx version. ```html {#- Template for the footer. -#} {%- block footer_before %}{%- endblock footer_before %} {%- if show_copyright and copyright|length -%} {%- if hasdoc('copyright') -%} {%- trans path=pathto('copyright'), copyright=copyright|e -%} © [Copyright]({{ path }}){{ copyright }} {%- endtrans -%} {%- else -%} {%- trans copyright=copyright|e -%} © {{ copyright }}  {%- endtrans -%} {%- endif -%} {%- endif -%} {%- if last_updated -%} {%- trans last_updated=last_updated|e -%} Last updated: {{ last_updated }}.  {%- endtrans -%} {%- endif -%} {%- if show_sphinx -%} {%- trans sphinx_version=sphinx_version|e -%} Built with [Sphinx {{ sphinx_version }}](https://www.sphinx-doc.org) {%- endtrans -%} {%- endif -%} {%- block footer_after %}{%- endblock footer_after %} ``` -------------------------------- ### Header Template Structure Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/header.html This snippet shows the Jinja2 template structure for the header, including blocks for logo, navigation, mobile menu, and search. ```html {#- Template file for the header -#} {#- Extra block at the top of the header -#} {%- block header\_before %}{% endblock header\_before -%} {#- show logo and extra header links on the left side of the header -#} {%- block header\_left %} {%- block header\_logo %} [{%- if logo\_url %} ![Logo]({{ logo\_url }}) {%- endif -%} {%- if theme\_logo_dark and not logo\_url %} ![Logo]({{ pathto('_static/' + theme_logo_dark, 1) }}) {%- endif -%} {%- if theme\_logo_light and not logo\_url %} ![Logo]({{ pathto('_static/' + theme_logo_light, 1) }}) {%- endif -%} {{ docstitle }}]({{ pathto\(master_doc) }}) {%- endblock header\_logo %} {%- block header\_main_nav %} {%- if theme\_main_nav_links|tobool -%} {%- for text,url in theme\_main_nav_links.items() %} {%- set \_active = "text-foreground" if pagename in url else "text-foreground/60" -%} {%- if url.startswith("http") %} [{{ text }}]({{ url }}) {%- else %} [{{ text }}]({{ pathto(url) }}) {%- endif %} {%- endfor %} {%- endif %} {%- endblock header\_main_nav -%} {%- block mobile\_menu %} {%- if sidebars|length >0 -%} Toggle navigation menu {%- endif -%} {%- endblock mobile\_menu %} {%- block header\_right %} {%- if docsearch or hasdoc('search') %} {%- include "searchbox.html" %} {%- endif %} {%- block extra\_header_link_icons %} {%- if theme\_extra_header_link_icons|tobool %} {%- for text,url in theme\_extra_header_link_icons.items() %} {%- if url is mapping %}[ {{ url.icon }} ]({{ url.link }} "{{ text }}"){% endif %} {%- endfor %} {%- endif %} {%- block theme\_switcher %} {%- endblock theme\_switcher %} {%- endblock extra\_header_link_icons %} {%- endblock header\_right %} {%- block header\_after %}{%- endblock header\_after %} ``` -------------------------------- ### Sidebar Template Logic Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/sidebar.html This Jinja template code defines the logic for rendering the sidebar, including conditional inclusion of navigation links and logos. ```html {#- Template for the sidebar. -#} {%- set only_main_nav = sidebars == ["sidebar_main_nav_links.html"] -%} {%- if not only_main_nav and sidebars|length > 0 -%} {%- else %} {%- endif %} [{%- if logo_url %} ![Logo]({{ logo_url }}) {%- endif -%} {%- if theme_logo_dark and not logo_url %} ![Logo]({{ pathto('_static/' + theme_logo_dark, 1) }}) {%- endif -%} {%- if theme_logo_light and not logo_url %} ![Logo]({{ pathto('_static/' + theme_logo_light, 1) }}) {%- endif -%} {{ docstitle }}]({{ pathto(master_doc) }}) {%- for section in sidebars %} {%- include section %} {%- endfor %} ``` -------------------------------- ### Title Suffix Logic Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/layout.html Jinja logic to determine the title suffix for the HTML page, considering the main document title and a potential document subtitle. ```html {%- if not embedded and docstitle -%} {%- if title == docstitle -%} {%- set titlesuffix = "" -%} {%- else -%} {%- set titlesuffix = " | "|safe + docstitle|e -%} {%- endif -%} {%- else -%} {%- set titlesuffix = "" -%} {%- endif -%} ``` -------------------------------- ### Language Attribute Macro Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/layout.html A Jinja macro to set the HTML lang attribute based on the language configuration. ```html {%- set lang_attr = "en" if language == None else (language|replace('_','-')) -%} ``` -------------------------------- ### Sidebar TOC Generation Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/sidebar_toc.html This Jinja template code controls the generation of the table of contents in the sidebar, conditionally including hidden items based on the theme's configuration. ```jinja {%- if theme_globaltoc_includehidden|tobool %} {{ toctree(titles_only=true, collapse=False, includehidden=true) }} {%- else %} {{ toctree(titles_only=true, collapse=False) }} {%- endif %} ``` -------------------------------- ### Sidebar Main Nav Links Template Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/sidebar_main_nav_links.html Jinja template for rendering main navigation links in the sidebar. ```html {#- Template for the main navigation links in the sidebar -#} {%- if theme_main_nav_links|tobool -%} {%- for text,url in theme_main_nav_links.items() %} {%- if url.startswith("http") %} [{{ text }}]({{ url }}) {%- else %} [{{ text }}]({{ pathto(url) }}) {%- endif %} {%- endfor %} {%- endif %} ``` -------------------------------- ### Jinja2 TOC Template Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_templates/toc.html This template defines the structure for generating an on-page table of contents using Jinja2. It includes conditional logic to check for metadata and a placeholder for the actual TOC content. ```html {%- if meta is mapping %} {%- if "hide-rtoc" not in meta %} {#- Template for the on-page TOC -#} {%- block toc_before %}{%- endblock -%} Page Contents {{ toc }} {%- block toc_after %}{%- endblock -%} {%- endif %} {%- endif %} ``` -------------------------------- ### Search Box Template Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_templates/searchbox.html This Jinja2 template defines the structure for a search box, conditionally rendering it based on the 'docsearch' variable. ```html {#- Template for the search box in the header. -#} {%- if docsearch %} {%- else %} 🔍︎ {%- endif -%} ``` -------------------------------- ### Sidebar TOC Jinja Template Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_templates/sidebar_toc.html This Jinja template code controls the inclusion of the table of contents in the sidebar, conditionally including hidden items based on the theme's global TOC setting. ```html {%- if theme_globaltoc_includehidden|tobool %} {{ toctree(titles_only=true, collapse=False, includehidden=true) }} {%- else %} {{ toctree(titles_only=true, collapse=False) }} {%- endif %} ``` -------------------------------- ### Breadcrumbs Template Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/breadcrumbs.html This Jinja template generates breadcrumbs for the documentation site. ```html {#- Template file for the breadcrumbs. -#} {%- set separator %} {{ theme_breadcrumbs_separator|default('/') }} {%- endset %} [{{ docstitle }}]({{ pathto(master_doc) }}) {{ separator }} {%- for doc in parents -%} [{{ doc.title }}]({{ doc.link|e }}) {{ separator }} {%- endfor -%} {{ title }} ``` -------------------------------- ### Search Fallback Script Source: https://github.com/jchanvfx/nodegraphqt/blob/main/docs/_themes/sphinxawesome_theme/search.html This JavaScript snippet hides a fallback message when JavaScript is enabled, allowing the search functionality to work. ```javascript document.querySelector("#fallback").style.display = "none" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.