Cannot expose webadmin in a subpath #297

Closed
opened 2026-10-05 04:10:57 +02:00 by adam · 18 comments
Owner

I would like to expose the webadmin site in a subpath instead of at the root, for example, at http://example.com/znc/. This is currently not possible, as all assets and pages are refered to with absolute paths; for example, the CSS is expected to live at the root:

<link rel="stylesheet" type="text/css" href="/pub/_default_.css" />

Ideally, assets and pages would be referred to with relative URLs, or a webroot variables should be available for templates for building the URLs.

I would like to expose the webadmin site in a subpath instead of at the root, for example, at `http://example.com/znc/`. This is currently not possible, as all assets and pages are refered to with absolute paths; for example, the CSS is expected to live at the root: ``` .html <link rel="stylesheet" type="text/css" href="/pub/_default_.css" /> ``` Ideally, assets and pages would be referred to with relative URLs, or a `webroot` variables should be available for templates for building the URLs. <!-- github-sync-id:26736308 -->
adam closed this issue 2026-10-05 04:10:58 +02:00
Author
Owner

This is possible by using "reverse proxy" techniques with your Web server. The specific configuration varies depending on HTTPd, but essentially you tell your front-end server to serve requests for a subdirectory from another "host". I haven't tested it, but I doubt that ZNC would have issues sending requests through an Apache or nginx front-end.

This is possible by using "reverse proxy" techniques with your Web server. The specific configuration varies depending on HTTPd, but essentially you tell your front-end server to serve requests for a subdirectory from another "host". I haven't tested it, but I doubt that ZNC would have issues sending requests through an Apache or nginx front-end. <!-- github-comment-id:33870646 -->
Author
Owner

There might be some rewrite logic involved too (to catch resources and either rewrite the requests or rewrite the page source) but I am certain this can be done without any changes to ZNC.

Why I can't edit my comment on mobile, I don't know. Silly GitHub.

There might be some rewrite logic involved too (to catch resources and either rewrite the requests or rewrite the page source) but I am certain this can be done without any changes to ZNC. Why I can't edit my comment on mobile, I don't know. Silly GitHub. <!-- github-comment-id:33870695 -->
Author
Owner

I am proxying the webadmin through nginx, using the newish TrustedProxy setting. The issue is that assets and pages use absolute links; the only thing similar to what you are suggesting that I can find is http://wiki.nginx.org/HttpSubModule, but it seems to be too simplistic.

In my opinion, some configuration option to set the web root for the links would facilitate things. That is the approach that, for example, Redmine uses.

I am proxying the webadmin through nginx, using the newish `TrustedProxy` setting. The issue is that assets and pages use absolute links; the only thing similar to what you are suggesting that I can find is http://wiki.nginx.org/HttpSubModule, but it seems to be too simplistic. In my opinion, some configuration option to set the web root for the links would facilitate things. That is the approach that, for example, [Redmine](http://www.redmine.org/projects/redmine/wiki/HowTo_Install_Redmine_in_a_sub-URI) uses. <!-- github-comment-id:33876366 -->
Author
Owner

The following is a draft of a possible way forward:

diff --git c/src/WebModules.cpp w/src/WebModules.cpp
index c8f1c65..2b3487a 100644
--- c/src/WebModules.cpp
+++ w/src/WebModules.cpp
@@ -319,6 +319,8 @@ void CWebSock::SetPaths(CModule* pModule, bool bIsTemplate) {
 }

 void CWebSock::SetVars() {
+   m_Template["BaseURI"] = "/";
+
    m_Template["SessionUser"] = GetUser();
    m_Template["SessionIP"] = GetRemoteIP();
    m_Template["Tag"] = CZNC::GetTag(GetSession()->GetUser() != NULL, true);
diff --git c/webskins/_default_/tmpl/BaseHeader.tmpl w/webskins/_default_/tmpl/BaseHeader.tmpl
index af63eaf..1ac6d68 100644
--- c/webskins/_default_/tmpl/BaseHeader.tmpl
+++ w/webskins/_default_/tmpl/BaseHeader.tmpl
@@ -5,12 +5,13 @@
    <head>
        <meta charset="UTF-8" />
        <title>ZNC - <? VAR Title DEFAULT="Web Frontend" ?></title>
+       <base href="<? VAR BaseURI ?>">
        <? LOOP CSSLoop ?>
-       <?IF HREF?><link rel="stylesheet" type="text/css" href="<? VAR HREF ?>" /><?ENDIF?>
+       <?IF HREF?><link rel="stylesheet" type="text/css" href=".<? VAR HREF ?>" /><?ENDIF?>
        <?ENDLOOP?>

        <? LOOP JSLoop ?>
-       <?IF HREF?><script type="text/javascript" src="<? VAR HREF ?>"></script><?ENDIF?>
+       <?IF HREF?><script type="text/javascript" src=".<? VAR HREF ?>"></script><?ENDIF?>
        <?ENDLOOP?>

        <? INC ExtraHeader.tmpl ?>
@@ -56,6 +57,7 @@
                            If you'd like to add your own local css file to be included after the global main.css,
                            you can make your own Header.tmpl like so...

+                               <!-- TODO: what to do with this href -->
                                <? ADDROW CSSLoop HREF=/pub/your_local.css ?>
                                <? ADDROW JSLoop HREF=/pub/your_local.js ?>
                                <? INC BaseHeader.tmpl ?>
diff --git c/webskins/_default_/tmpl/LoginBar.tmpl w/webskins/_default_/tmpl/LoginBar.tmpl
index a489905..991c9d7 100644
--- c/webskins/_default_/tmpl/LoginBar.tmpl
+++ w/webskins/_default_/tmpl/LoginBar.tmpl
@@ -1,9 +1,9 @@
                <? IF LoggedIn ?>
-               <span class="logoutbox"><a href="/logout">Logout</a></span>
+               <span class="logoutbox"><a href="./logout">Logout</a></span>
                <? ELSE IF !ModName && PageName == "login" ?>
                <span class="logoutbox">&nbsp;</span>
                <? ELSE ?>
-               <form action="/login" method="post">
+               <form action="./login" method="post">
                    <div class="loginbox">
                        <input type="hidden" name="submitted" value="1" />
                        User:<input type="text" name="user" />
diff --git c/webskins/_default_/tmpl/Menu.tmpl w/webskins/_default_/tmpl/Menu.tmpl
index 97cfaa3..6295bca 100644
--- c/webskins/_default_/tmpl/Menu.tmpl
+++ w/webskins/_default_/tmpl/Menu.tmpl
@@ -1,14 +1,14 @@
 <div id="menu">
    <ul class="nav">
-       <li class="topitem<? IF !ModName && PageName == "index" ?> active<? ENDIF ?>"><a href="/">Home</a></li>
+       <li class="topitem<? IF !ModName && PageName == "index" ?> active<? ENDIF ?>"><a href="./">Home</a></li>

        <? IF GlobalModLoop ?>
            <li class="topitem parent"><span class="title">Global Modules</span>
                <ul>
                <? LOOP GlobalModLoop SORTASC=ModName ?>
-                   <li class="modtitle<? IF Active ?> active<? ENDIF ?>"><a href="<? VAR ModPath ?>"><? VAR Title ?></a></li>
+                   <li class="modtitle<? IF Active ?> active<? ENDIF ?>"><a href=".<? VAR ModPath ?>"><? VAR Title ?></a></li>
                    <? LOOP SubPageLoop ?>
-                       <li class="subitem<? IF Active ?> active<? ENDIF ?>"><a href="<? VAR ModPath ?><? VAR PageName ?><? IF Params ?>?<? VAR Params ?><? ENDIF ?>"><? VAR Title ?></a></li>
+                       <li class="subitem<? IF Active ?> active<? ENDIF ?>"><a href=".<? VAR ModPath ?><? VAR PageName ?><? IF Params ?>?<? VAR Params ?><? ENDIF ?>"><? VAR Title ?></a></li>
                    <? ENDLOOP ?>
                <? ENDLOOP ?>
                </ul>
@@ -19,9 +19,9 @@
            <li class="topitem parent"><span class="title">User Modules</span>
                <ul>
                <? LOOP UserModLoop SORTASC=ModName ?>
-                   <li class="modtitle<? IF Active ?> active<? ENDIF ?>"><a href="<? VAR ModPath ?>"><? VAR Title ?></a></li>
+                   <li class="modtitle<? IF Active ?> active<? ENDIF ?>"><a href=".<? VAR ModPath ?>"><? VAR Title ?></a></li>
                    <? LOOP SubPageLoop ?>
-                       <li class="subitem<? IF Active ?> active<? ENDIF ?>"><a href="<? VAR ModPath ?><? VAR PageName ?><? IF Params ?>?<? VAR Params ?><? ENDIF ?>"><? VAR Title ?></a></li>
+                       <li class="subitem<? IF Active ?> active<? ENDIF ?>"><a href=".<? VAR ModPath ?><? VAR PageName ?><? IF Params ?>?<? VAR Params ?><? ENDIF ?>"><? VAR Title ?></a></li>
                    <? ENDLOOP ?>
                <? ENDLOOP ?>
                </ul>
@@ -34,9 +34,9 @@
                    <li class="topitem parent"><span class="title">Network Modules (<? VAR NetworkName ?>)</span>
                        <ul>
                        <? LOOP ModLoop SORTASC=ModName ?>
-                           <li class="modtitle<? IF Active ?> active<? ENDIF ?>"><a href="<? VAR ModPath ?>"><? VAR Title ?></a></li>
+                           <li class="modtitle<? IF Active ?> active<? ENDIF ?>"><a href=".<? VAR ModPath ?>"><? VAR Title ?></a></li>
                            <? LOOP SubPageLoop ?>
-                               <li class="subitem<? IF Active ?> active<? ENDIF ?>"><a href="<? VAR ModPath ?><? VAR PageName ?><? IF Params ?>?<? VAR Params ?><? ENDIF ?>"><? VAR Title ?></a></li>
+                               <li class="subitem<? IF Active ?> active<? ENDIF ?>"><a href=".<? VAR ModPath ?><? VAR PageName ?><? IF Params ?>?<? VAR Params ?><? ENDIF ?>"><? VAR Title ?></a></li>
                            <? ENDLOOP ?>
                        <? ENDLOOP ?>
                        </ul>

Changing the base uri to + m_Template["BaseURI"] = "/irc/"; makes assets and links be requested from the subpath; but, for example, redirects are still directed to the / root.

All in all, I think the best way is to offer a BaseURI setting, and make OnPageRequest strip it, Redirect prefix it and change the templates to either explicitely prefix the links with it or use the <base> approach in the above diff.

Does it make sense?

The following is a draft of a possible way forward: ``` .patch diff --git c/src/WebModules.cpp w/src/WebModules.cpp index c8f1c65..2b3487a 100644 --- c/src/WebModules.cpp +++ w/src/WebModules.cpp @@ -319,6 +319,8 @@ void CWebSock::SetPaths(CModule* pModule, bool bIsTemplate) { } void CWebSock::SetVars() { + m_Template["BaseURI"] = "/"; + m_Template["SessionUser"] = GetUser(); m_Template["SessionIP"] = GetRemoteIP(); m_Template["Tag"] = CZNC::GetTag(GetSession()->GetUser() != NULL, true); diff --git c/webskins/_default_/tmpl/BaseHeader.tmpl w/webskins/_default_/tmpl/BaseHeader.tmpl index af63eaf..1ac6d68 100644 --- c/webskins/_default_/tmpl/BaseHeader.tmpl +++ w/webskins/_default_/tmpl/BaseHeader.tmpl @@ -5,12 +5,13 @@ <head> <meta charset="UTF-8" /> <title>ZNC - <? VAR Title DEFAULT="Web Frontend" ?></title> + <base href="<? VAR BaseURI ?>"> <? LOOP CSSLoop ?> - <?IF HREF?><link rel="stylesheet" type="text/css" href="<? VAR HREF ?>" /><?ENDIF?> + <?IF HREF?><link rel="stylesheet" type="text/css" href=".<? VAR HREF ?>" /><?ENDIF?> <?ENDLOOP?> <? LOOP JSLoop ?> - <?IF HREF?><script type="text/javascript" src="<? VAR HREF ?>"></script><?ENDIF?> + <?IF HREF?><script type="text/javascript" src=".<? VAR HREF ?>"></script><?ENDIF?> <?ENDLOOP?> <? INC ExtraHeader.tmpl ?> @@ -56,6 +57,7 @@ If you'd like to add your own local css file to be included after the global main.css, you can make your own Header.tmpl like so... + <!-- TODO: what to do with this href --> <? ADDROW CSSLoop HREF=/pub/your_local.css ?> <? ADDROW JSLoop HREF=/pub/your_local.js ?> <? INC BaseHeader.tmpl ?> diff --git c/webskins/_default_/tmpl/LoginBar.tmpl w/webskins/_default_/tmpl/LoginBar.tmpl index a489905..991c9d7 100644 --- c/webskins/_default_/tmpl/LoginBar.tmpl +++ w/webskins/_default_/tmpl/LoginBar.tmpl @@ -1,9 +1,9 @@ <? IF LoggedIn ?> - <span class="logoutbox"><a href="/logout">Logout</a></span> + <span class="logoutbox"><a href="./logout">Logout</a></span> <? ELSE IF !ModName && PageName == "login" ?> <span class="logoutbox">&nbsp;</span> <? ELSE ?> - <form action="/login" method="post"> + <form action="./login" method="post"> <div class="loginbox"> <input type="hidden" name="submitted" value="1" /> User:<input type="text" name="user" /> diff --git c/webskins/_default_/tmpl/Menu.tmpl w/webskins/_default_/tmpl/Menu.tmpl index 97cfaa3..6295bca 100644 --- c/webskins/_default_/tmpl/Menu.tmpl +++ w/webskins/_default_/tmpl/Menu.tmpl @@ -1,14 +1,14 @@ <div id="menu"> <ul class="nav"> - <li class="topitem<? IF !ModName && PageName == "index" ?> active<? ENDIF ?>"><a href="/">Home</a></li> + <li class="topitem<? IF !ModName && PageName == "index" ?> active<? ENDIF ?>"><a href="./">Home</a></li> <? IF GlobalModLoop ?> <li class="topitem parent"><span class="title">Global Modules</span> <ul> <? LOOP GlobalModLoop SORTASC=ModName ?> - <li class="modtitle<? IF Active ?> active<? ENDIF ?>"><a href="<? VAR ModPath ?>"><? VAR Title ?></a></li> + <li class="modtitle<? IF Active ?> active<? ENDIF ?>"><a href=".<? VAR ModPath ?>"><? VAR Title ?></a></li> <? LOOP SubPageLoop ?> - <li class="subitem<? IF Active ?> active<? ENDIF ?>"><a href="<? VAR ModPath ?><? VAR PageName ?><? IF Params ?>?<? VAR Params ?><? ENDIF ?>"><? VAR Title ?></a></li> + <li class="subitem<? IF Active ?> active<? ENDIF ?>"><a href=".<? VAR ModPath ?><? VAR PageName ?><? IF Params ?>?<? VAR Params ?><? ENDIF ?>"><? VAR Title ?></a></li> <? ENDLOOP ?> <? ENDLOOP ?> </ul> @@ -19,9 +19,9 @@ <li class="topitem parent"><span class="title">User Modules</span> <ul> <? LOOP UserModLoop SORTASC=ModName ?> - <li class="modtitle<? IF Active ?> active<? ENDIF ?>"><a href="<? VAR ModPath ?>"><? VAR Title ?></a></li> + <li class="modtitle<? IF Active ?> active<? ENDIF ?>"><a href=".<? VAR ModPath ?>"><? VAR Title ?></a></li> <? LOOP SubPageLoop ?> - <li class="subitem<? IF Active ?> active<? ENDIF ?>"><a href="<? VAR ModPath ?><? VAR PageName ?><? IF Params ?>?<? VAR Params ?><? ENDIF ?>"><? VAR Title ?></a></li> + <li class="subitem<? IF Active ?> active<? ENDIF ?>"><a href=".<? VAR ModPath ?><? VAR PageName ?><? IF Params ?>?<? VAR Params ?><? ENDIF ?>"><? VAR Title ?></a></li> <? ENDLOOP ?> <? ENDLOOP ?> </ul> @@ -34,9 +34,9 @@ <li class="topitem parent"><span class="title">Network Modules (<? VAR NetworkName ?>)</span> <ul> <? LOOP ModLoop SORTASC=ModName ?> - <li class="modtitle<? IF Active ?> active<? ENDIF ?>"><a href="<? VAR ModPath ?>"><? VAR Title ?></a></li> + <li class="modtitle<? IF Active ?> active<? ENDIF ?>"><a href=".<? VAR ModPath ?>"><? VAR Title ?></a></li> <? LOOP SubPageLoop ?> - <li class="subitem<? IF Active ?> active<? ENDIF ?>"><a href="<? VAR ModPath ?><? VAR PageName ?><? IF Params ?>?<? VAR Params ?><? ENDIF ?>"><? VAR Title ?></a></li> + <li class="subitem<? IF Active ?> active<? ENDIF ?>"><a href=".<? VAR ModPath ?><? VAR PageName ?><? IF Params ?>?<? VAR Params ?><? ENDIF ?>"><? VAR Title ?></a></li> <? ENDLOOP ?> <? ENDLOOP ?> </ul> ``` Changing the base uri to `+ m_Template["BaseURI"] = "/irc/";` makes assets and links be requested from the subpath; but, for example, redirects are still directed to the `/` root. All in all, I think the best way is to offer a `BaseURI` setting, and make `OnPageRequest` strip it, `Redirect` prefix it and change the templates to either explicitely prefix the links with it or use the `<base>` approach in the above diff. Does it make sense? <!-- github-comment-id:33876596 -->
Author
Owner

I am sorry for the spam. The OnPageRequest is not needed, as the reverse proxy is already stripping it, and the Redirect should also not be needed, as http://wiki.nginx.org/NginxHttpProxyModule#proxy_redirect should be able to deal with that.

What do you thing of the approach above?

I am sorry for the spam. The `OnPageRequest` is not needed, as the reverse proxy is already stripping it, and the `Redirect` should also not be needed, as http://wiki.nginx.org/NginxHttpProxyModule#proxy_redirect should be able to deal with that. What do you thing of the approach above? <!-- github-comment-id:33876929 -->
Author
Owner

I would be careful of using <base> as it modifies the default behavior of links: http://stackoverflow.com/q/1889076/5991

Modifying the templates to explicitly prefix the links is probably the better approach. Is there a possible use case where one server would want to have, say, a different BaseURI for each Web-enabled Listener?

I would be careful of using `<base>` as it modifies the default behavior of links: http://stackoverflow.com/q/1889076/5991 Modifying the templates to explicitly prefix the links is probably the better approach. Is there a possible use case where one server would want to have, say, a different `BaseURI` for each Web-enabled Listener? <!-- github-comment-id:33877066 -->
Author
Owner

As an issue, this is duplicate of #138 (which was at some point turned into a pull request)
But that pull request isn't complete (e.g. it misses all those href= changes); if you make this work, it would be great.

As an issue, this is duplicate of #138 (which was at some point turned into a pull request) But that pull request isn't complete (e.g. it misses all those `href=` changes); if you make this work, it would be great. <!-- github-comment-id:33878880 -->
Author
Owner

Well, depends on the what the use case for having multiple listeners is. I guess the answer is yes: if you want to have listeners on different interfaces/ports, there is no reason to have them exposed via some same subpath.

About the <base>, yes, should probably use the <? VAR BaseURI ?> prefixing each URI, instead of making them relative.

Well, depends on the what the use case for having multiple listeners is. I guess the answer is yes: if you want to have listeners on different interfaces/ports, there is no reason to have them exposed via some same subpath. About the `<base>`, yes, should probably use the `<? VAR BaseURI ?>` prefixing each URI, instead of making them relative. <!-- github-comment-id:33879325 -->
Author
Owner

@DarthGandalf, I don't know how I missed that issue. What do you think of the issue raised by @dgw? The commit you pointed at assumes that the prefix is global. Should it be per-listener?

@DarthGandalf, I don't know how I missed that issue. What do you think of the issue raised by @dgw? The commit you pointed at assumes that the prefix is global. Should it be per-listener? <!-- github-comment-id:33879557 -->
Author
Owner

I have seen that there is a CHTTPSock::SetDocRoot method. Do you think that we can implement a solution at that level?

I have seen that there is a `CHTTPSock::SetDocRoot` method. Do you think that we can implement a solution at that level? <!-- github-comment-id:33879852 -->
Author
Owner

Per-listener sounds good.
DocRoot seems to be directory on file system, which limits access for statically served files. E.g. to protect /etc/passwd. And it doesn't seem to be used o_O

Per-listener sounds good. DocRoot seems to be directory on file system, which limits access for statically served files. E.g. to protect /etc/passwd. And it doesn't seem to be used o_O <!-- github-comment-id:33881449 -->
Author
Owner

I won't be working on this soon, but will post any updates.

Best regards.

I won't be working on this soon, but will post any updates. Best regards. <!-- github-comment-id:33897703 -->
Author
Owner

This is a design question.

The URIPrefix can be different for each listener. The plan is to add a member variable m_sURIPrefix holding it. The issue is how to let the CWebSock know about it.
a) CWebSock accepts the URIPrefix as a constructor argument. In this case CIncomingConnection would receive it as an argument in the constructor as well and would pass it to the CWebSocket constructor.
b) Sockets, both IRC and HTTP, receive the listener that accepted them as a constructor argument. This way they have the listener settings available from the socket. This can be useful for various modules; for example, WebAdmin needs to know which one is the current listener in order to prevent the user killing it. In my view, it is sensible for the sockets to know which listener has spawned them.

I am missing something? What do you think?

This is a design question. The URIPrefix can be different for each listener. The plan is to add a member variable `m_sURIPrefix` holding it. The issue is how to let the `CWebSock` know about it. a) CWebSock accepts the URIPrefix as a constructor argument. In this case CIncomingConnection would receive it as an argument in the constructor as well and would pass it to the CWebSocket constructor. b) Sockets, both IRC and HTTP, receive the listener that accepted them as a constructor argument. This way they have the listener settings available from the socket. This can be useful for various modules; for example, WebAdmin needs to know which one is the current listener in order to prevent the user killing it. In my view, it is sensible for the sockets to know which listener has spawned them. I am missing something? What do you think? <!-- github-comment-id:34358355 -->
Author
Owner

"b)" looks more extensible, yes. Webadmin now compares only port number to understand that.
But it would add a dependency loop CWebSock->CListener->CWebSock
On the other hand, ZNC is already a mess from OOP point of view :-( Probably CIncomingConnection should use abstract factories of socket classes instead.

"b)" looks more extensible, yes. Webadmin now compares only port number to understand that. But it would add a dependency loop CWebSock->CListener->CWebSock On the other hand, ZNC is already a mess from OOP point of view :-( Probably CIncomingConnection should use abstract factories of socket classes instead. <!-- github-comment-id:34386710 -->
Author
Owner

With regards to the previous question, I'm going with route "b)". I don't see the dependency CListener->CWebSock: the listener knows about the listener socket (CRealListener), but once the connection is accepted, no trace of the spawned socket seems to remain on the listener.

I will post a pull request during the day showing the approach, and would appreciate comments and code review.

Right now, the biggest block is that I don't seem to be able to get a template variable's value from within a loop. The case is, I want to change the lines from:

<? LOOP CSSLoop ?>
    <?IF HREF?><link rel="stylesheet" type="text/css" href="<? VAR HREF ?>" /><?ENDIF?>
<?ENDLOOP?>

into:

<? LOOP CSSLoop ?>
    <?IF HREF?><link rel="stylesheet" type="text/css" href="<? VAR URIPrefix ?><? VAR HREF ?>" /><?ENDIF?>
<?ENDLOOP?>

but, although the URIPrefix is defined in the outer scope, it seems not to be available inside the loop. How can I make it available.

With regards to the previous question, I'm going with route "b)". I don't see the dependency CListener->CWebSock: the listener knows about the listener socket (CRealListener), but once the connection is accepted, no trace of the spawned socket seems to remain on the listener. I will post a pull request during the day showing the approach, and would appreciate comments and code review. Right now, the biggest block is that I don't seem to be able to get a template variable's value from within a loop. The case is, I want to change the [lines](https://github.com/znc/znc/blob/master/webskins/_default_/tmpl/BaseHeader.tmpl#L8-L10) from: ``` .html <? LOOP CSSLoop ?> <?IF HREF?><link rel="stylesheet" type="text/css" href="<? VAR HREF ?>" /><?ENDIF?> <?ENDLOOP?> ``` into: ``` .html <? LOOP CSSLoop ?> <?IF HREF?><link rel="stylesheet" type="text/css" href="<? VAR URIPrefix ?><? VAR HREF ?>" /><?ENDIF?> <?ENDLOOP?> ``` but, although the `URIPrefix` is defined in the outer scope, it seems not to be available inside the loop. How can I make it available. <!-- github-comment-id:34543072 -->
Author
Owner

CListener->CRealListener->CIncomingConnection->CWebSock
"->" means "creates" in this case, the name of class is directly used in
functions of the other class

And it's not "although", outer scope is not accessible from inner scope,
right. Not sure why, but that's by design (probably it was just easier
this way). At least, in other places where inner scope needs access to
outer scope, the needed vars are explicitly copied to inner scope in .cpp.

08.02.2014 12:42, uu1101 пишет:

With regards to the previous question, I'm going with route "b)". I
don't see the dependency CListener->CWebSock: the listener knows about
the listener socket (CRealListener), but once the connection is
accepted, no trace of the spawned socket seems to remain on the listener.

I will post a pull request during the day showing the approach, and
would appreciate comments and code review.

Right now, the biggest block is that I don't seem to be able to get a
template variable's value from within a loop. The case is, I want to
change the lines
https://github.com/znc/znc/blob/master/webskins/default/tmpl/BaseHeader.tmpl#L8-L10
from:

<?IF HREF?><link rel="stylesheet" type="text/css" href="<? VAR HREF ?>" /><?ENDIF?>
<?ENDLOOP?>

into:

<?IF HREF?><link rel="stylesheet" type="text/css" href="<? VAR URIPrefix ?><? VAR HREF ?>" /><?ENDIF?>
<?ENDLOOP?>

but, although the |URIPrefix| is defined in the outer scope, it seems
not to be available inside the loop. How can I make it available.

—
Reply to this email directly or view it on GitHub
https://github.com/znc/znc/issues/480#issuecomment-34543072.

CListener->CRealListener->CIncomingConnection->CWebSock "->" means "creates" in this case, the name of class is directly used in functions of the other class And it's not "although", outer scope is not accessible from inner scope, right. Not sure why, but that's by design (probably it was just easier this way). At least, in other places where inner scope needs access to outer scope, the needed vars are explicitly copied to inner scope in .cpp. 08.02.2014 12:42, uu1101 пишет: > With regards to the previous question, I'm going with route "b)". I > don't see the dependency CListener->CWebSock: the listener knows about > the listener socket (CRealListener), but once the connection is > accepted, no trace of the spawned socket seems to remain on the listener. > > I will post a pull request during the day showing the approach, and > would appreciate comments and code review. > > Right now, the biggest block is that I don't seem to be able to get a > template variable's value from within a loop. The case is, I want to > change the lines > https://github.com/znc/znc/blob/master/webskins/_default_/tmpl/BaseHeader.tmpl#L8-L10 > from: > > <? LOOP CSSLoop ?> > <?IF HREF?><link rel="stylesheet" type="text/css" href="<? VAR HREF ?>" /><?ENDIF?> > <?ENDLOOP?> > > into: > > <? LOOP CSSLoop ?> > <?IF HREF?><link rel="stylesheet" type="text/css" href="<? VAR URIPrefix ?><? VAR HREF ?>" /><?ENDIF?> > <?ENDLOOP?> > > but, although the |URIPrefix| is defined in the outer scope, it seems > not to be available inside the loop. How can I make it available. > > — > Reply to this email directly or view it on GitHub > https://github.com/znc/znc/issues/480#issuecomment-34543072. <!-- github-comment-id:34547577 -->
Author
Owner

I see how AddModLoop fills all needed variables for each row, but those loops are constructed entirely in .cpp. CSSLoop and JSLoop rows are added via ADDROW directly in the templates; I don't see how can I stuff the URIPrefix there via .cpp.

I have created a pull request with current status of the change, and would appreciate any comments.

I see how AddModLoop fills all needed variables for each row, but those loops are constructed entirely in .cpp. CSSLoop and JSLoop rows are added via ADDROW directly in the templates; I don't see how can I stuff the URIPrefix there via .cpp. I have created a pull request with current status of the change, and would appreciate any comments. <!-- github-comment-id:34548109 -->
Author
Owner

It looks like you can use a variable from the outermost scope: <? VAR Foo TOP ?>
See https://github.com/znc/znc/blob/master/src/Template.cpp#L812 and how it's used in existing stuff.

It looks like you can use a variable from the outermost scope: `<? VAR Foo TOP ?>` See https://github.com/znc/znc/blob/master/src/Template.cpp#L812 and how it's used in existing stuff. <!-- github-comment-id:34554895 -->
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adam/znc#297