Web page shown in a widget?

I want to display the output of this URL (https://pla.co.uk/pla-api-integration/ebb-tide-widget-embed) in a widget but struggling to get it to work…
Any help appreciated

There’s no straightforward way just to put the exact webpage output into a widget. You’ll have to parse the resulting HTML and take the data you need and then build the widget.

That said, this script should give you the same layout as the webpage. I’ve made some assumptions though based on the current output of the page.

Hope this helps.

CleanShot 2024-04-09 at 20.01.01@2x

Current HTML:

<div class="dashinner" style="font-family: Cabin Variable, sans-serif; text-align: center"><h4>Ebb Tide Flag</h4><div class="line"></div><div class="tidecont"><img src="/modules/custom/pla_api_integration/assets/flag_yellow.png" loading="lazy" alt="" class="tideflag"><div><strong>CAUTION - STRONG<br></strong>Fluvial Flows</div></div></div>

Assumptions:

  • there’s always a title enclosed in a <h4> tag
  • there’s always an image of a flag
  • there’s a bold caution line
  • there’s another line of text after the bold caution line

Widget script:

async function getData() {

  const url = 'https://pla.co.uk/pla-api-integration/ebb-tide-widget-embed'
  const req = new Request(url)
  const html = await req.loadString()

  const title = html.match(/(?<=h4\>).+(?=<\/h4)/)[0]
  let flagUrl = html.match(/(?<=src=").+?(?=")/)[0]
  flagUrl = `https://pla.co.uk${flagUrl}`

  const footer = html.split('tideflag">')[1]
  const caution = footer.match(/(?<=strong>).+(?=<br)/)[0]
  const desc = footer.match(/(?<=\/strong>).+?(?=<\/div)/)[0]

  return {
    title, flagUrl, caution, desc
  }

}


const data = await getData()

const widget = new ListWidget()
widget.backgroundColor = Color.white()
widget.addSpacer()

const title = widget.addText(data.title)
title.font = Font.boldSystemFont(15)
title.textColor = Color.black()
title.centerAlignText()

const imgReq = new Request(data.flagUrl)
const img = await imgReq.loadImage()
const flag = widget.addImage(img)
flag.centerAlignImage()

const caution = widget.addText(data.caution)
caution.font = Font.boldSystemFont(10)
caution.textColor = Color.black()
caution.centerAlignText()

const desc = widget.addText(data.desc)
desc.font = Font.regularSystemFont(12)
desc.textColor = Color.black()
desc.centerAlignText()

widget.addSpacer()

Script.setWidget(widget)

if (config.runsInApp) {
  await widget.presentSmall()
}
1 Like

Thank you so much (even Copilot could not help me with this!).
I assume it will work for the other coloured flags (it can also be red, black or green).
Would you like an attribution if I publish this?
Cheers

Yes, it should work with other flags, it just reads whatever’s loaded on the page.

I’ll leave the attribution up to you. It’s fine either way.