Flutter HTML模板渲染插件html_template的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter HTML模板渲染插件html_template的使用

html_template简介

html_template 是一个基于Dart的服务器端HTML模板引擎。它支持多种特性,包括但不限于自动补全和静态分析、经典的控制流结构(如 *if*for*switch)、条件添加CSS类和HTML属性、变量自动转义以及在IntelliJ-based IDE中的语法高亮。

intellij-screenshot

特性

  • 自动补全和静态分析:在模板中提供智能提示和错误检查。
  • 经典控制流结构
    • 条件语句:*if
    • 循环语句:*for
    • 分支语句:*switch
  • 条件添加CSS类和HTML属性
    • CSS类:[class.my-class]="$condition"
    • HTML属性:[disabled]="$condition"
  • 自动转义变量:确保输出的安全性。
  • 语法高亮:在支持的IDE中提供更好的阅读体验。

示例代码

定义模板函数

import 'package:html_template/html_template.dart';

part 'main.g.dart';

@template
void _productTemplate(Product product) {
  '''
  <img *if="${product.icon != null}" src="${product.icon}" />
  <h1 [class.new]="${product.isNew}">$product</h1>
  ''';
}

@template
void _pageTemplate(Product product, {List<String>? scripts}) {
  var script = '';
  '''
<html lang="${Language.current}">
  <head>
    <title>${product.name} - My site</title>
    <script *for="$script in $scripts" src="$script" async></script>
  </head>
  <body>
    ${productTemplate(product)}
  </body>
</html>
  ''';
}

生成代码

通过命令行工具生成代码:

dart run build_runner watch --delete-conflicting-outputs

这将生成与原始方法签名相同的公共方法。例如:

TrustedHtml productTemplate(Product product) {
  var $ = StringBuffer();

  $.write('  ');
  if (product.icon != null) {
    $.write('<img src="${TrustedHtml.escape.attribute(product.icon)}">');
  }
  $.write('\n  ');
  $.write('<h1${template.classAttribute({'new': product.isNew})}>');
  $.write('${TrustedHtml.escape(product)}');
  $.write('</h1>');
  $.write('\n  ');

  return TrustedHtml($.toString());
}

使用模板

调用生成的公共方法来构建HTML页面:

void main() {
  router.get('/products/<id>', (request) async {
    var product = await database.findProduct(params(request, 'id'));

    // Create the html for the response from the Product of your database
    var html = pageTemplate(product);

    return Response.ok(html, headers: {'content-type': 'text/html'});
  });
}

条件语句示例

@template
void _conditionExample({required bool someCondition}) async {
  '''  
  <!-- Conditionally include the <h2> tag -->
  <h2 *if="$someCondition">Condition on a tag</h2>
  
  <!-- Include the 'disabled' attribute if the condition is true -->
  <input [disabled]="$someCondition"/>
  
  <!-- Add 'my-class' CSS class if the condition is true -->
  <input [class.my-class]="$someCondition">
  
  <!-- Use any Dart expression for the condition -->
  <hr *if="${(await fetchData()).isEmpty}"/>
  ''';
}

循环示例

@template
void _simpleLoop(List<MenuItem> menu) {
  MenuItem? item;
  '''
  <ul>
    <li *for="${item!} in $menu">
      ${item.title}
    </li>
  </ul>
  ''';
}

Switch语句示例

@template
void _switchExample(Season season) {
  '''
<div *switch="$season">
  <span *case="${Season.summer}">Hot</span>
  <span *case="${Season.winter}">Cold</span>
  <div *default>Pleasant</div>
</div>
  ''';
}

CSS类示例

@template
void _cssClassesExample(List<Data> data, {bool showMenu = false}) {
  // Add classes based on condition
  '<li [class.active]="$showMenu" [class.enabled]="${data.isNotEmpty}">Actif</li>';

  // We can pass a Map<String, bool> to the [classes] attribute
  var myClasses = {'enabled': showMenu};
  '<a type="text" [classes]="$myClasses"></a>';
}

Dart代码示例

@template
void _movieTemplate() async {
  '<h1>My movies</h1>';

  var page = await fetchPage();
  if (!page.isLoggedIn) {
    '<h2>Log in</h2>';
  } else {
    '<ul>';
    for (var movie in page.myMovies) {
      '<li [class.favorite]="${movie.isFavorite}">$movie</li>';
    }
    '</ul>';
  }
  '<footer>Footer</footer>';
}

嵌套模板和主布局

@template
void _myTemplate() {
  '''
  <h1>Images</h1>
  ${img('landscape.png')}
  ''';
}

@template
void _img(String url) {
  '<img src="$url">';
}

其他注意事项

  • 使用 <text *if=".." >xx</text> 标签可以在不包含HTML元素的情况下输出文本。
  • 在Dart文件中使用以下注释以避免linter警告:
// ignore_for_file: unnecessary_statements

总结

html_template 提供了一种强大且灵活的方式来处理服务器端的HTML模板渲染。通过结合Dart语言的强大功能和简洁的模板语法,开发者可以更高效地创建动态网页内容。希望这篇指南能帮助你在Flutter项目中更好地利用 html_template 插件。


更多关于Flutter HTML模板渲染插件html_template的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter HTML模板渲染插件html_template的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用html_template插件来渲染HTML模板的示例代码。这个插件允许你将HTML字符串渲染为Flutter的Widget。

首先,确保你已经将html_template插件添加到了你的pubspec.yaml文件中:

dependencies:
  flutter:
    sdk: flutter
  html_template: ^x.y.z  # 替换为最新版本号

然后,运行flutter pub get来安装依赖。

以下是一个完整的示例代码,展示了如何使用html_template插件:

import 'package:flutter/material.dart';
import 'package:html_template/html_template.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter HTML Template Rendering',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final String htmlTemplate = """
  <html>
    <body>
      <h1>Hello, Flutter!</h1>
      <p>This is a paragraph rendered from an HTML template.</p>
      <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
      </ul>
    </body>
  </html>
  """;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('HTML Template Rendering'),
      ),
      body: Center(
        child: HtmlTemplate(
          html: htmlTemplate,
          onLinkTap: (url) {
            // Handle link taps, e.g., open in a browser
            print('Link tapped: $url');
          },
          onImageTap: (src) {
            // Handle image taps, if needed
            print('Image tapped: $src');
          },
          // Optionally, you can provide custom styles or additional rendering options
          customRenderers: {
            'p': (context, attributes, children) {
              return Padding(
                padding: EdgeInsets.all(8.0),
                child: Text(
                  children.join(),
                  style: TextStyle(fontSize: 16),
                ),
              );
            },
          },
        ),
      ),
    );
  }
}

在这个示例中:

  1. MyApp类定义了一个基本的Flutter应用程序。
  2. MyHomePage类包含一个HTML模板字符串htmlTemplate,其中包含了一些简单的HTML内容。
  3. HtmlTemplate Widget用于渲染这个HTML模板。
  4. onLinkTaponImageTap回调函数用于处理链接和图片的点击事件。
  5. customRenderers参数允许你自定义HTML标签的渲染方式,这里我们自定义了<p>标签的渲染,添加了内边距和字体大小。

你可以根据需要修改HTML模板和自定义渲染器,以适应你的应用需求。确保在实际项目中替换html_template: ^x.y.z为当前可用的最新版本号。

回到顶部