Skip to main content
gFly v1.15.1
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Views

Note
IMPORTANT!
The view file should be placed in directory resources/views

Pongo2 is very popular and a community-built template engine with syntax inspired by Django-syntax.

Let create a HomePage controller file home_page.go by embedding BaseBase file generic_page.go as below:

package page

import "github.com/gflydev/core"

// ====================================================================
// ======================== Controller Creation =======================
// ====================================================================

// NewHomePage As a constructor to create a Home Page.
func NewHomePage() *HomePage {
    return &HomePage{}
}

type HomePage struct {
    BasePage 
}

// ====================================================================
// ========================= Request Handling =========================
// ====================================================================

func (m *HomePage) Handle(c *core.Ctx) error {
    return m.View(c, "home", core.Data{
        "hero_text": "gFly - Laravel inspired web framework written in Go",
    })
}
Note

IMPORTANT!
You can add some common parameters and custom function for template generic_page.go in directory app/http/controllers/page/

Eg:

    // -------------- Append data --------------
    if _, exists := data["title_page"]; !exists {
        data["title_page"] = "gFly | Laravel inspired web framework written in Go"
    }

    if c.GetData(constants.User) != nil {
        // Auto-load login user session
        user := c.GetData(constants.User).(models.User)

        data["account"] = user
    }

    // -------------- Append functions --------------
    data["isPaths"] = func(paths ...string) bool {
        return utils.IndexOfStr(paths, c.Path()) >= 0
    }
    data["formatTime"] = func(t time.Time) string {
        return t.Format("2006-01-02 15:04:05")
    }
    data["nullString"] = func(v sql.NullString) string {
        return *dbNull.StringVal(v)
    }

View template resources/views/home.tpl

{% extends "master.tpl" %}
    {% block body %}
    <!-- =========={ Hero }==========  -->
    <div id="hero">
      {{ hero_text }}
    </div><!-- end hero -->
    {% endblock %}

View template resources/views/master.tpl

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <!-- Required meta tags -->
  <meta charset="UTF-8"/>
  <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>

  <!-- Title  -->
  <title>{{ title_page }}</title>
</head>
<body>
<!-- =========={ MAIN }==========  -->
<main id="content">
  {% block body %}
  {% endblock %}
</main><!-- end main -->
</script>
</body>
</html>

Use-cases

List/Collection

import (
  "gfly/app/domain/models"
  "gfly/app/http/controllers/page"
  "github.com/gflydev/core"
  mb "github.com/gflydev/db"
)

...

func (m *ListPage) Handle(c *core.Ctx) error {
    users, total, err := mb.FindModels[models.User](1, 10, "id", qb.Desc)
    if err != nil {
        return c.Error(err)
    }

    return m.View(c, "user", core.Data{
        "users": users,
        "total": total,
    })
}
<ul>
{% for user in users %}
    <li>{{ user.ID }} - {{ user.Email }} - {{ user.Fullname }}</li>
{% endfor %}
</ul>

Caveats

Filters

  • date / time: The date and time filter are taking the Golang specific time- and date-format (not Django’s one) currently. Take a look on the format here.
  • stringformat: stringformat does not take Python’s string format syntax as a parameter, instead it takes Go’s. Essentially {{ 3.14|stringformat:"pi is %.2f" }} is fmt.Sprintf("pi is %.2f", 3.14).
  • escape / force_escape: Unlike Django’s behaviour, the escape-filter is applied immediately. Therefore there is no need for a force_escape-filter yet.

Tags

  • for: All the forloop fields (like forloop.counter) are written with a capital letter at the beginning. For example, the counter can be accessed by forloop.Counter and the parentloop by forloop.Parentloop.
  • now: takes Go’s time format (see date and time-filter).

Misc

  • not in-operator: You can check whether a map/struct/string contains a key/field/substring by using the in-operator (or the negation of it): {% if key in map %}Key is in map{% else %}Key not in map{% endif %} or {% if !(key in map) %}Key is NOT in map{% else %}Key is in map{% endif %}.

Add-ons, libraries and helpers

Official

  • pongo2-addons - Official additional filters/tags for pongo2 (for example a markdown-filter). They are in their own repository because they’re relying on 3rd-party-libraries.

3rd-party