5

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?

JJJ
  • 32,902
  • 20
  • 89
  • 102

2 Answers2

2

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.

Kai Sellgren
  • 27,954
  • 10
  • 75
  • 87
  • well, there is no reason why `build.dart` can't be extended to simply rewrite a file when another file changes. ugly, sure, but not really complicated – Zdeslav Vojkovic Jun 02 '13 at 22:23
  • I don't really need server side rendering, just an "insert that file right here as it is before rendering this page", but I suppose that feature would cover it as well. – JJJ Jun 03 '13 at 08:42
  • Oh well, just remember that @Zdeslav's solution doesn't scale at all :) – Kai Sellgren Jun 03 '13 at 11:01
  • @KaiSellgren, sure, with more than 1 file, I am afraid what kind of rebuild loop it would trigger. wrong tool for the job, definitely :) – Zdeslav Vojkovic Jun 03 '13 at 11:35
2

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.

Zdeslav Vojkovic
  • 14,391
  • 32
  • 45
  • right, it's ugly as hell :) Actually, I thought about building a library for this, but decided not to, as it is not something I would like to see often. – Zdeslav Vojkovic Jun 03 '13 at 08:57
  • @Juhana, BTW, initially I thought about rewriting only the files in the `out` directory, but editor also monitors these files (I think there is a bug submitted for this) so it triggers an infinite rebuilding loop – Zdeslav Vojkovic Jun 03 '13 at 09:00