all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [PATCH cluster/manager v2 0/2] Configurable window titles for nodes
@ 2026-07-20 10:03 Thomas Ellmenreich
  2026-07-20 10:03 ` [PATCH manager v2 1/2] fix #5475: configurable window title Thomas Ellmenreich
  2026-07-20 10:03 ` [PATCH cluster v2 2/2] " Thomas Ellmenreich
  0 siblings, 2 replies; 3+ messages in thread
From: Thomas Ellmenreich @ 2026-07-20 10:03 UTC (permalink / raw)
  To: pve-devel; +Cc: Thomas Ellmenreich

Thank you @Dominik Csapak and @Thomas Lamprecht for your comments.

Configurable window titles for nodes
====================================

Currently the window title is fixed to the following string:

$nodename - Proxmox Virtual Environment

This has become problematic for users with multiple clusters, each containing
the same node name. To help distinguish between tabs, it has been requested [1]
that the window title be made configurable with the fqdn as an option.

[1] https://bugzilla.proxmox.com/show_bug.cgi?id=5475

Implementation
--------------

After considering the different options, I have deemed a server side
implementation, through the datacenter.cfg, to be the better option.
Specifically because of its durability across sessions and because it
automatically configures the title for all users and all nodes across the
cluster.

The config now contains a new ui-settings format string which then in turn
contains a 'title' enum field for the window title. This enum string will then
be converted to a window title and inserted in the index.html.tpl template on
every request.

The current enum options are:

- default - Displays the default '$nodename - Proxmox Virtual Environment' string
  if the config enum is not present

- 'node-and-cluster' - Displays the nodename and then the clustername in the
  following style: '$nodename - $clustername - Proxmox Virtual Environment'

- 'fqdn' - Displays the current fqdn as returned by `PVE::Tools::get_fqdn()`
  like so: '$fqdn - Proxmox Virtual Environment'


Possible future extensions
--------------------------

- If proper cross-node user settings are implemented in the future, they could
  be used to allow users to define their own window title settings and have
  these settings be persisted across sessions

- One of the selection options for window titles could be a user defined
  template string which would allow users of PVE to define their own
  window titles.

Changes since v1
----------------

- Instead of storing the 'window-title' setting directly in the datacenter.cfg
  its now nested in a more general 'ui-settings' format string. This allows
  easier expansion in the future

- All adjustments that were needed to create the 'ui-settings' format string

Changes since RFC
-----------------

- change of the `datacenter.cfg` setting title from "windowtitle" to
  "window-title"

- renamed `nodeandcluster` to `node-and-cluster`

- added the " - Proxmox Virtual Environment" trailer to all titles

- removed the questions from this text and added the "Possible future
  extensions" section


pve-manager:

Thomas Ellmenreich (1):
  fix #5475: configurable window title

 PVE/Service/pveproxy.pm       | 21 ++++++++++++
 www/index.html.tpl            |  2 +-
 www/manager6/UIOptions.js     |  6 ++++
 www/manager6/dc/OptionView.js | 61 +++++++++++++++++++++++++++++++++++
 4 files changed, 89 insertions(+), 1 deletion(-)


pve-cluster:

Thomas Ellmenreich (1):
  fix #5475: configurable window title

 src/PVE/DataCenterConfig.pm | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)


Summary over all repositories:
  5 files changed, 114 insertions(+), 1 deletions(-)

-- 
Generated by murpp 0.12.0




^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH manager v2 1/2] fix #5475: configurable window title
  2026-07-20 10:03 [PATCH cluster/manager v2 0/2] Configurable window titles for nodes Thomas Ellmenreich
@ 2026-07-20 10:03 ` Thomas Ellmenreich
  2026-07-20 10:03 ` [PATCH cluster v2 2/2] " Thomas Ellmenreich
  1 sibling, 0 replies; 3+ messages in thread
From: Thomas Ellmenreich @ 2026-07-20 10:03 UTC (permalink / raw)
  To: pve-devel; +Cc: Thomas Ellmenreich

Allow setting of the new 'ui-settings' format string and the nested
'title' property. Setting this property defines the window titles
for all cluster nodes.

Signed-off-by: Thomas Ellmenreich <t.ellmenreich@proxmox.com>
---
 PVE/Service/pveproxy.pm       | 21 ++++++++++++
 www/index.html.tpl            |  2 +-
 www/manager6/UIOptions.js     |  6 ++++
 www/manager6/dc/OptionView.js | 61 +++++++++++++++++++++++++++++++++++
 4 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/PVE/Service/pveproxy.pm b/PVE/Service/pveproxy.pm
index c6011a00..811295f4 100755
--- a/PVE/Service/pveproxy.pm
+++ b/PVE/Service/pveproxy.pm
@@ -202,6 +202,24 @@ my sub get_path_mtime {
     return $mtime;
 }
 
+# builds the window title from the datacenter.cfg configuration
+my $get_window_title = sub {
+    my ($title_enum, $nodename) = @_;
+
+    my $title = "$nodename";
+
+    if ($title_enum eq "node-and-cluster") {
+        my $clinfo = PVE::Cluster::get_clinfo();
+        my $clustername = $clinfo->{cluster}->{name};
+
+        $title = "$nodename - $clustername";
+    } elsif ($title_enum eq "fqdn") {
+        $title = PVE::Tools::get_fqdn();
+    }
+
+    return $title . " - Proxmox Virtual Environment";
+};
+
 # NOTE: Requests to those pages are not authenticated so we must be very careful here
 sub get_index {
     my ($nodename, $server, $r, $args) = @_;
@@ -232,10 +250,12 @@ sub get_index {
         }
     }
 
+    my $window_title;
     my $consent_text;
     eval {
         my $dc_conf = PVE::Cluster::cfs_read_file('datacenter.cfg');
         $consent_text = $dc_conf->{'consent-text'};
+        $window_title = $get_window_title->($dc_conf->{'ui-settings'}->{'title'}, $nodename);
 
         if (!$lang) {
             $lang = $dc_conf->{language} // 'en';
@@ -276,6 +296,7 @@ sub get_index {
         token => $token,
         console => $args->{console},
         nodename => $nodename,
+        window_title => $window_title,
         debug => $debug,
         version => "$version",
         wtversion => $wtversion,
diff --git a/www/index.html.tpl b/www/index.html.tpl
index 74ee02d9..5138b7cc 100644
--- a/www/index.html.tpl
+++ b/www/index.html.tpl
@@ -4,7 +4,7 @@
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
-    <title>[% nodename %] - Proxmox Virtual Environment</title>
+    <title>[% window_title %]</title>
     <link rel="icon" sizes="128x128" href="/pve2/images/logo-128.png" />
     <link rel="apple-touch-icon" sizes="128x128" href="/pve2/images/logo-128.png" />
     <link rel="stylesheet" type="text/css" href="/pve2/ext6/theme-crisp/resources/theme-crisp-all.css?ver=7.0.0" />
diff --git a/www/manager6/UIOptions.js b/www/manager6/UIOptions.js
index 8c4674af..bb0af8d5 100644
--- a/www/manager6/UIOptions.js
+++ b/www/manager6/UIOptions.js
@@ -90,6 +90,12 @@ Ext.define('PVE.UIOptions', {
         alphabetical: gettext('Alphabetical'),
     },
 
+    titleOptions: {
+        __default__: '$nodename - Proxmox Virtual Environment',
+        'node-and-cluster': '$nodename - $clustername - Proxmox Virtual Environment',
+        fqdn: '$fqdn - Proxmox Virtual Environment',
+    },
+
     shouldSortTags: function () {
         return !(PVE.UIOptions.options['tag-style']?.ordering === 'config');
     },
diff --git a/www/manager6/dc/OptionView.js b/www/manager6/dc/OptionView.js
index dc12aa7e..208cc147 100644
--- a/www/manager6/dc/OptionView.js
+++ b/www/manager6/dc/OptionView.js
@@ -91,6 +91,67 @@ Ext.define('PVE.dc.OptionView', {
             defaultValue: '__default__',
             deleteEmpty: true,
         });
+        me.rows['ui-settings'] = {
+            required: true,
+            renderer: (value) => {
+                if (value === undefined) {
+                    return gettext('No Overrides');
+                }
+                let txt = '';
+                if (value.title) {
+                    txt += Ext.String.format(gettext('Title: {0}'), value.title);
+                }
+                return txt;
+            },
+            header: gettext('Ui Settings'),
+            editor: {
+                xtype: 'proxmoxWindowEdit',
+                width: 800,
+                subject: gettext('Ui Settings'),
+                fieldDefaults: {
+                    labelWidth: 100,
+                },
+                url: '/api2/extjs/cluster/options',
+                items: [
+                    {
+                        xtype: 'inputpanel',
+                        setValues: function (values) {
+                            if (values === undefined) {
+                                return undefined;
+                            }
+                            values = values?.['ui-settings'] ?? {};
+                            values.title = values.title || '__default__';
+                            return Proxmox.panel.InputPanel.prototype.setValues.call(this, values);
+                        },
+                        onGetValues: function (values) {
+                            let style = {};
+                            if (values.title) {
+                                style.title = values.title;
+                            }
+                            let value = PVE.Parser.printPropertyString(style);
+                            if (value === '') {
+                                return {
+                                    delete: 'ui-settings',
+                                };
+                            }
+                            return {
+                                'ui-settings': value,
+                            };
+                        },
+                        items: [
+                            {
+                                xtype: 'proxmoxKVComboBox',
+                                name: 'title',
+                                fieldLabel: gettext('Title'),
+                                comboItems: Object.entries(PVE.UIOptions.titleOptions),
+                                deleteEmpty: true,
+                                defaultValue: '__default__',
+                            },
+                        ],
+                    },
+                ],
+            },
+        };
         me.add_text_row('email_from', gettext('Email from address'), {
             deleteEmpty: true,
             vtype: 'proxmoxMail',
-- 
2.47.3





^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH cluster v2 2/2] fix #5475: configurable window title
  2026-07-20 10:03 [PATCH cluster/manager v2 0/2] Configurable window titles for nodes Thomas Ellmenreich
  2026-07-20 10:03 ` [PATCH manager v2 1/2] fix #5475: configurable window title Thomas Ellmenreich
@ 2026-07-20 10:03 ` Thomas Ellmenreich
  1 sibling, 0 replies; 3+ messages in thread
From: Thomas Ellmenreich @ 2026-07-20 10:03 UTC (permalink / raw)
  To: pve-devel; +Cc: Thomas Ellmenreich

Added a new 'ui-settings' format string to the datacenter.cfg. Currently
only contains a 'title' option to determine the window title of the
nodes browser tab.

Signed-off-by: Thomas Ellmenreich <t.ellmenreich@proxmox.com>
---
 src/PVE/DataCenterConfig.pm | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/src/PVE/DataCenterConfig.pm b/src/PVE/DataCenterConfig.pm
index 004122e..751d8ed 100644
--- a/src/PVE/DataCenterConfig.pm
+++ b/src/PVE/DataCenterConfig.pm
@@ -344,6 +344,16 @@ my $user_tag_privs_format = {
     },
 };
 
+my $ui_settings_format = {
+    'title' => {
+        optional => 1,
+        type => 'string',
+        enum => ['node-and-cluster', 'fqdn'],
+        description =>
+            "Define the text displayed in the browser tab title for all nodes in this cluster.",
+    },
+};
+
 my $datacenter_schema = {
     type => "object",
     additionalProperties => 0,
@@ -436,6 +446,12 @@ my $datacenter_schema = {
             # FIXME: remove 'applet' with 9.0 (add pve8to9 check!)
             enum => ['applet', 'vv', 'html5', 'xtermjs'],
         },
+        'ui-settings' => {
+            optional => 1,
+            type => "string",
+            format => $ui_settings_format,
+            description => "For cluster wide ui settings.",
+        },
         email_from => {
             optional => 1,
             type => 'string',
@@ -618,6 +634,10 @@ sub parse_datacenter_config {
         $res->{'tag-style'} = parse_property_string($tag_style_format, $tag_style);
     }
 
+    if (my $ui_settings = $res->{'ui-settings'}) {
+        $res->{'ui-settings'} = parse_property_string($ui_settings_format, $ui_settings);
+    }
+
     if (my $user_tag_privs = $res->{'user-tag-access'}) {
         $res->{'user-tag-access'} = parse_property_string($user_tag_privs_format, $user_tag_privs);
 
@@ -711,6 +731,11 @@ sub write_datacenter_config {
         $cfg->{'tag-style'} = PVE::JSONSchema::print_property_string($tag_style, $tag_style_format);
     }
 
+    if (ref(my $ui_settings = $cfg->{'ui-settings'})) {
+        $cfg->{'ui-settings'} =
+            PVE::JSONSchema::print_property_string($ui_settings, $ui_settings_format);
+    }
+
     if (ref(my $user_tag_privs = $cfg->{'user-tag-access'})) {
         if (my $user_tags = $user_tag_privs->{'user-allow-list'}) {
             $user_tag_privs->{'user-allow-list'} = join(';', sort $user_tags->@*);
-- 
2.47.3





^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-07-20 10:04 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-20 10:03 [PATCH cluster/manager v2 0/2] Configurable window titles for nodes Thomas Ellmenreich
2026-07-20 10:03 ` [PATCH manager v2 1/2] fix #5475: configurable window title Thomas Ellmenreich
2026-07-20 10:03 ` [PATCH cluster v2 2/2] " Thomas Ellmenreich

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal