Lock a collection of html pages behind anvil login

What I’m trying to do:
I am trying to have a collection of html pages, which link to eachother, locked behind an anvil login page
What I’ve tried and what’s not working:
My first step was to try and have a form with a link that opened an html page in assets, but those seem to be for forms only

I dont really have enough code or webtools to share, but if someone knows what part of the docs to look at, that would be great! I couldnt figure out how to have the custom html templates just be a fully different webpage instead

Hi John, and welcome to the forum!

What do you mean by collection of html pages?

With Anvil you create a Single Page App, and the app shows forms and data without changing the url.

It is possible to add assets to an app and have them served from their own url. They could be images, plain html pages, etc., but they would be publicly visible, without any authentication check.

Perhaps you could store your html pages in a datatable text column and show them in a custom html form, but the browser will have that html inside some container elements and with the whole javascript app.

It’s difficult to answer without knowing what you mean by collection of html pages.

Hi! Thanks!

I have ~259 html pages where each page has some bokeh plots, some tables, and some links to other pages

Are the assets necessarily publicly accessible? If I had the bokeh plots in the assets, could I then select which one I read?

Assets are public, as far as I know, you can’t add any authentication or other checks.

Anvil is not a framework to serve existing html.

Again, you provide very little information, so I’m going to play the guess game.

You could add your html pages to a text column of an HtmlPages table and your images to a media column of an Images table.

Create a form visible only to authenticated users with a custom html component, get the html from the table, search the text for all the original links to images and replace them with links to the media stored in the Images table, search for links to other pages and replace them with clickable elements that will trigger an event in the form that you can use to show the next page.

It depends on the complexity of the html. If it’s simple, you could use a RichText component and set it to (restricted) html. It would make it easier to manage the substitutions mentioned above.

Another solution could be to create an uplink script that analyzes all the html pages, extracts the info and organizes it in some tables. Then the app does what Anvil apps do best: show info from tables in whatever format you like for whatever user you like.

You basically create a scraper that scrapes your own html pages. I have done this many times, it’s much easier and reliable than going through the substitutions mentioned above. I have apps with scheduled tasks that do it nightly.

But I don’t know if you can do it, because I don’t know anything about your data.

Very sorry for not providing sufficent information, my html pages are just

  1. a navbar with links to other html pages in the collection
  2. bokeh plots and tables rendered in html, via Working with Plot and Renderers — HoloViews v1.15.4
  3. the javascript and boilerplate generated by the holoview bokeh plot renderer
  4. some text

I am not sure what other details would help avoid the guessing game, hopefully this clarifies

But knowing that anvil is not the place to go to serve existing html is probably the key, and I should look elsewhere, if I am following what you are saying correctly, the html is probably too complex?

Thanks!

Anvil is fine for serving custom HTML. As Stefano says, you do not want to put it into Assets, but into a data table and pull the HTML from the data table and display it after you authenticate the user.

Here’s an app that allows you to type HTML into the text box. When you click the button that custom HTML is displayed. If instead you pull the HTML from a data table, you can display that HTML. https://angelic-profitable-outcome.anvil.app

Do note that the HTML should not be a full page (e.g. no html tag, no head tag, no body tag), but just the portion of the HTML you actually care about.

Here’s a clone of the app so you can see how to display custom HTML: Anvil | Login

3 Likes

You could have your logged in page with a simple init or form_show which includes:

if anvil.users.get_user():
    self.menu_column.visible = True
else:
   open_form(‘Start’)

Then, if you had your custom HTML set up as forms just have button clicks which replace your imported forms in the content_panel:

At the top of the form code:

from ..HMTLForm1 import ..HTMLForm1
from ..HMTLForm2 import ..HTMLForm2

Then in your menu item Something1’s button click event:

def something1_click(self,**args):
   self.content_panel.clear()
   self.content_panel.add_component(HTMLForm1)

Won’t be perfect as I’m putting the kids to bed but lots of explainers for this in the forum and docs.

The navigation bar would not work. You would need to strip it out of the original html and create a new one. Or do some heavy text substitution.