Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling Web UI components to the HTML

I'm building a simple web site in Dart Web UI. Each page has a header (with site navigation) and a footer. I've used components for the header and footer, and each page looks something like this:

<!DOCTYPE html>
<html>
<head>
    <title>Test</title>

    <link rel="import" href="header.html">
    <link rel="import" href="footer.html">
</head>

<body>
    <header-component></header-component>

    Page content...

    <footer-component></footer-component>
</body>
</html>

This works well, but the components aren't inserted to the HTML itself but loaded dynamically from Dart (or JavaScript) code. Is there some way to have the Web UI compiler insert the header and footer to the HTML file itself so that they would be visible to search engines and to users who have JavaScript disabled?

like image 234
JJJ Avatar asked Oct 04 '22 23:10

JJJ


2 Answers

There isn't a direct way to do this.

This is typically a server-side task: the server takes care to generate the required HTML.

Web components are all about client side, so they work on what's already delivered to the browser.

However, build.dart scripts is executed each time a file in your project changes so you can extend the script to get what you want. I don't think this is a good approach, but it solves your problem.

First add the following placeholder to the target html file (in my case web/webuitest.html):

<header></header>

Now add a header.html file to your project with some content:

THIS IS A HEADER

Now extend the build.dart script so it will check if the header.html was modified, and if it was, it will update webuitest.html:

// if build.dart arguments contain header.html in the list of changed files
if (new Options().arguments.contains('--changed=web/header.html')) {
    // read the target file
    var content = new File('web/webuitest.html').readAsStringSync();
    // read the header
    var hdr = new File('web/header.html').readAsStringSync();
    // now replace the placeholder with the header
    // NOTE: use (.|[\r\n])* to match the newline, as multiLine switch doesn't work as I expect
    content = content.replaceAll(
        new RegExp("<header>(.|[\r\n])*</header>", multiLine:true), 
        '<header>${hdr}</header>');
    // rewrite the target file with modified content
    new File('web/webuitest.html').writeAsStringSync(content);
  }

One consequence of this approach is that rewriting the target will trigger build.dart once again, so output files will be built twice, but that's not a big issue.

Of course, this can be made much better, and someone could even wrap it into a library.

like image 153
Zdeslav Vojkovic Avatar answered Oct 13 '22 10:10

Zdeslav Vojkovic


Currently, no, it's not possible. What you want is server-side rendering of those templates so that you can serve them directly to the client when they request your pages (including search spiders).

You might want to keep track of this issue however: https://github.com/dart-lang/web-ui/issues/107?source=c

When it's finished things are looking better.

like image 21
Kai Sellgren Avatar answered Oct 13 '22 10:10

Kai Sellgren