flutter-view
  • Introduction
  • FAQ
  • Get Started
    • Install
    • Usage
    • Test drive
    • VS Code support
    • Examples
  • Guide
    • Configuring flutter-view
    • Creating a new view
    • Creating widget layouts
    • Flow control
    • Shortcuts
    • Styling with CSS
    • Writing Reactive code
    • Styling per platform
  • Shortcuts Reference
    • Special pug tags
    • CSS style properties
Powered by GitBook
On this page
  • Overview
  • Adding children to widgets
  • Automatic columns
  • Calling dart factory constructors
  • Passing children instead of child
  • Passing const widgets
  • Passing parameters
  • String parameters
  • Expression parameters
  • Unnamed parameters
  • Escaping parameter names
  • Passing complex parameter values
  • Passing functions as children
  • Passing handlers
  • Passing Arrays
  • Automatic Containers
  1. Guide

Creating widget layouts

Overview

In Flutter, widget trees are built by passing a child or children. Widget trees have a lot of indentation, especially since in Flutter nearly everything is a widget, and composition is preferred to inheritance. This can lead to complex nesting and child parameters.

Flutter-views are optimised for building widget trees. Pug in particular is well suited for creating tree structures and moving parts around.

The following example generates a Dart method FooPage(), which returns a Scaffold with an AppBar, and a centralized greeting message.

The Pug creates the layout, and the main.dart file uses this layout to render the app. This separation between layout and logic is fundamental to using flutter-view.

foo-page.pug
foo-page(flutter-view :greeting)
    scaffold
        app-bar(as='appBar')
            container(as='title') Foo Page
        center(as='body') Hello $greeting!
foo-page.dart
FooPage({@required greeting}) {
    return Scaffold(
        appBar: AppBar(
            title: Container(
                child: Text('Foo page'),
            ),
        ),
        body: Center(
            child: Text('Hello $greeting!'),
        ),
    );
}
main.dart
import 'package:flutter/material.dart';
import 'foo-page.dart';

void main() => runApp(TestApp());

class TestApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Test App',
      home: FooPage(greeting: 'world!')
    );
  }

}

Adding children to widgets

In a flutter-view, add indented child tags to tags to automatically have them assigned as child or children parameters.

In flutter-view Pug/HTML content, an HTML tag is a method or constructor call, and its parameters are parameters for this method or constructor. The tag children are assigned as the Flutter child/children parameters.

To see how this works, compare the Pug and generated Dart code in this example:

container
    column
        row 
            text(value='first row!')
        row 
            text(value='second row!')
        row
            flat-button 
                text(value='Click me!')
            
return Container(
    child: Column(
        children: [
            Row(
                children: [
                    Text('first row!'),
                ],
            ),
            Row(
                children: [
                    Text('second row!'),
                ],
            Row(
                FlatButton(
                    child: Text('Click me!'),
                )
            ),
        ],
    ),
);

Automatic columns

container
    row first row!
    row second row!
    row
        flat-button Click me!            
return Container(
    child: Column(
        children: [
            Row(
                children: [
                    Text('first row!'),
                ],
            ),
            Row(
                children: [
                    Text('second row!'),
                ],
            Row(
                FlatButton(
                    child: Text('Click me!'),
                )
            ),
        ],
    ),
);

Calling dart factory constructors

To call the factory constructor instead of the default constructor, pass the constructor after the class name, separated with a colon.

button-theme:bar
    | some content here
ButtonTheme.bar(
    child: Text(
        'some content here'
    ),
)

Passing children instead of child

There may be cases where flutter-view does not recognise your tag needs a children parameter instead of a child parameter. In that case use and array and assign it as children:

column
    array(as='children')
        row first!
        row second!
Column(
    children: [
        Row(
            children: [
                Text('first!'),
            ]
        ),
        Row(
            children: [
                Text('second!'),
            ]
        ),
    ]
)

Passing const widgets

For optimising performance, you may want to pass some widgets as constants. You can do this by adding a const parameter in a widget:

To see how this works, compare the Pug and generated Dart code in this example:

container
    column(const)
        row 
            text(value='first row!')
return Container(
    child: const Column(
        children: [
            Row(
                children: [
                    Text('first row!'),
                ],
            ),
        ],
    ),
);

Passing parameters

To pass parameters besides child or children, you pass them as pug/html parameters.

String parameters

You can pass strings by using quotes. Both double and single quotes work.

For example:

banner(title='testing')
    | Hello world!
return Banner(
    title: 'testing',
    child: Text('Hello world!'),
);

Expression parameters

To assign a Dart expression as the value of a parameter:

  • start the parameter name with :

  • wrap the expression in quotes. You may need to escape strings.

For example:

flat-button(:color='highlighted ? Colors.red : Colors.grey')
    | Click me!     
return FlatButton(
    color: highlighted ? Colors.red : Colors.grey,
    child: Text('Click me!'),
);

For title we want to pass a direct string, but for color we want to pass a value by reference, so we add : in front of the parameter.

Unnamed parameters

Some widgets take an unnamed parameter in their constructor. You can pass this using the reserved value parameter:

container
    icon(:value='Icons.add')
    text(value='Hello world')
return Container(
    child: Column(
        children: [
            Icon(Icons.add),
            Text('Hello world'),
        ]
    ),
);

Escaping parameter names

You may need to pass a parameter that has the name of a reserved keyword, such as value. You can bypass this problem by escaping your parameter with the ^ sign:

:^value='foo'

Passing complex parameter values

Sometimes what you want to pass is not just a single value, but a value that is constructed of many widgets. To solve this, you may take a child and use the as keyword to assign it as a parameter to the parent widget.

scaffold
    app-bar(as='appBar')
        container(as='title') Test App
    center(as='body') Hello world!
return Scaffold(
    appBar: AppBar(
        title: Container(
            child: Text('Test App'),
        ),
        body: Center(
            child: Text('Hello world!'),
        ),
    ),
);

Passing functions as children

Passing handlers

Passing a handler function or closure is no different than in Dart:

my-button(flutter-view :on-click[Function])
    flat-button(:on-pressed='onClick') Click me!

A common case is a closure without any parameters. In that case you can use the @ sign to create a closure handler:

my-button(flutter-view)
    flat-button(@on-pressed='print("Click!")') Click me!
MyButton() {
    return FlatButton(
        onPressed: () { print("Click!"); },
        child: Text('Click me!'),
    );
}

Passing Arrays

Sometimes you need to pass an array of specific items to a parameter. In that case you can use the array tag.

custom-scroll-view
    array(as='slivers')
        sliver1
        sliver2
        sliver3
CustomScrollView(
    slivers: [
        sliver1,
        sliver2,
        sliver3,
    ],
)

Automatic Containers

container hello world
#greeting hello world
.greeting hello world

All three are equivalent and convert to:

Container(
    child: Text('hello world'),
)

The classes and ids you use are forgotten after the conversion to Dart code. However, you do get automatic commenting, which will make it easier to read the generated code.

The biggest benefit is however that you can use them to style your widgets.

PreviousCreating a new viewNextFlow control

Last updated 3 years ago

Flutter-view knows which classes generally need children instead of single child, and automatically creates when you pass multiple children. Also, if you pass text, flutter-view it automatically wraps it in a widget as well. This together allows you to be more terse:

You can in flutter-view.json.

Some Flutter Dart classes may use factory constructors. For example, ButtonTheme has a constructor.

The class used above has no child or children parameters. Instead we add two children and assign them as parameters using the as property.

You can create functions that return children using the .

A nice Pug feature is that classes and ids are automatically converted into DIV tags. In flutter-view, they are automatically converted into widgets:

Columns
Text
ButtonTheme.bar()
Scaffold
Container
function shortcut
override the default wrapper