Custom Index and Login Template Does Not Work

Just the past few days been tinkering with this and going through the Panel source code on Github, but to no avail.

Here is what is going on:

  1. For creating a basic custom login template passed in using the --basic-login-template flag when calling panel serve, the template actually manages to render correctly, however, any images or favicons locally hosted are not found/rendered.

  2. For the index template (ending with .html) passed in through the --index flag the server straight up skips the custom template and instead renders the default Panel index page. As beautiful as this page is, the action packed light paths across a dark background really steal away from a pink background I am trying to put instead.

All in all I am not sure what is necessarily the issue here. I already loaded my assets and thumbnails in the appropriate directories when calling pn.serve so those aren’t an issue, it seems just the templates at the moment.

1 Like

Hi @robml

Would it be possible for you to create a minimum, reproducible example? Without it, it requires a lot of effort on the supporting side to try to reproduce, analyze and fix.

Hey @Marc definitely.

For both cases I run the following command:
panel serve app.py --basic-login-template login.html --cookie-secret 123 --index index.html where the value for cookie-secret is a placeholder here.

For case #1, the basic-login-template I used is based on the default one with the only changes being to the image which is stored locally.

And the only places I change in the default template which I named login.html is:

<!-- Uses the template from https://github.com/bokeh/bokeh/tree/branch-3.2/examples/server/app/server_auth -->
...
<html>
...
    <title>MYAPPNAME | Login</title>
    <!-- For the below, I store all the images and icons in a folder called 'assets' -->
    <link rel="apple-touch-icon" sizes="180x180" href="assets/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="assets/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="assets/favicon-16x16.png">
    <link rel="manifest" href="assets/site.webmanifest">
    <link rel="icon" type="image/x-icon" href="assets/favicon.ico">
    <style>
    ...
    </style>
</head>
<body>
  <div class="wrap">
    <form class="login-form" action="./login" method="post">
      <div class="form-header">
        <!-- The following image along with the favicon above do not render -->
        <h3><img id="logo" src="assets/MYLOGO.jpg" width="150" height="150"></h3>
        <br>
        <p> Login to access MYAPPNAME</p>
      </div>
      ...
</html>

where I use ellipsis (...) to denote parts of the default template that I left unchanged.

For the second (#2) issue, I pass the following template but it never shows up automatically redirecting me to the default index template. Note, although based off of the original template on Github, I made more changes but I highlighted in comments where they are and used ellipsis again to denote where the template stayed the same as the original on Github.

<html lang="en">
<head>
  <!-- Basic Page Needs
  -------------------------------------------------- -->
  <meta charset="utf-8">
  <title>MYAPPNAME</title>
  ...

  <!-- Favicon - again images and icons are in the folder 'assets'
  -------------------------------------------------- -->
  <link rel="apple-touch-icon" sizes="180x180" href="assets/apple-touch-icon.png">
  <link rel="icon" type="image/png" sizes="32x32" href="assets/favicon.ico">
  <link rel="manifest" href="assets/site.webmanifest">
  <meta name="msapplication-TileColor" content="#da532c">
  <meta name="theme-color" content="#ffffff">
  <script type="module" src="{{ PANEL_CDN }}bundled/@microsoft/fast-components@2.30.6/dist/fast-components.js"></script>
  <script type="module" src="{{ PANEL_CDN }}bundled/fast/js/fast_design.js"></script>
  <script type="text/javascript">
    ...
  </script>

  <style>
    ...
  </style>
</head>
<body>
  <fast-design-system-provider id="body-design-provider" use-defaults>
    <fast-design-system-provider id="header-design-provider" use-defaults>
<!-- I removed the theme toggle switch here -->
      <section class="header">
        <div class="header-content">
          <div>
            <fast-anchor id="title" href="." appearance="neutral" target="_self">
            <!-- Notice how I keep everything the same except the 'src' -->
              <img id="panel-logo" src="assets/MYLOGO.jpg"/>
            </fast-anchor>
            <fast-tooltip anchor="title">Click to visit the MYAPP web site</fast-tooltip>
          </div>
          <span id="subtitle">Running MYAPP</span>
        </div>
      </section>
    </fast-design-system-provider>
    <section class="search">
      <fast-text-field id="search-input" placeholder="search" onInput="hideCards(event.target.value)"></fast-text-field>
    </section>
    <section id="cards">
      <ul class="cards-grid">
        {% for item in sorted(items, key=lambda item: item[1:].replace("_", " ").title()) %}
        <li class="card">
          <a class="card-link" href=".{{ item }}" id="{{ item }}">
            <fast-card class="gallery-item">
              <!- for <object data...> I replaced the 'thumbnails' folder with 'assets' -->
	      <object data="assets{{ item }}.png" type="image/png">
               ...
</body>
</html>

Finally, for completeness, I did place the target images both in an assets folder as well as a assets/thumbnails folder, to which I added to my path in pn.serve using the argument static_dirs={'assets': './assets','thumbnails':'./assets/thumbnails'}.

Any light you can shed here would be immensely helpful. For the login page my workaround was to use the Internet facing URL link of the image, but that might not work in production as we might end up using this in an intranet.

As for the index page, I just don’t know what to make of it. Thank you for taking the time to look into this.

@Marc checking if you may have missed my last reply.

EDIT (something I forgot to add on):
I wanted to add on that upon starting a server on the last few runs with the above setup I get the following Traceback assertion error, however the server does continue to run:

2023-09-14 04:26:05,784 Error running application handler <bokeh.application.handlers.script.ScriptHandler object at 0x000001A51DB19270>:
File 'windows_events.py', line 319, in run_forever:
assert self._self_reading_future is None 
Traceback (most recent call last):
  File "C:\Users\robjr\miniconda3\envs\safeyouenv\lib\site-packages\bokeh\application\handlers\code_runner.py", line 231, in run
    exec(self._code, module.__dict__)
  File "C:\Users\robjr\Desktop\SafeYou\v3\panel_app\app3.py", line 267, in <module>
    pn.serve({
  File "C:\Users\robjr\miniconda3\envs\safeyouenv\lib\site-packages\panel\io\server.py", line 872, in serve
    return get_server(panels, **kwargs)
  File "C:\Users\robjr\miniconda3\envs\safeyouenv\lib\site-packages\panel\io\server.py", line 1148, in get_server   
    server.io_loop.start()
  File "C:\Users\robjr\miniconda3\envs\safeyouenv\lib\site-packages\tornado\platform\asyncio.py", line 195, in start

    self.asyncio_loop.run_forever()
  File "C:\Users\robjr\miniconda3\envs\safeyouenv\lib\asyncio\windows_events.py", line 319, in run_forever
    assert self._self_reading_future is None
AssertionError