Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

views-markup: How to use linkGenerator in included templates #214

Open
mariogarcia opened this issue Dec 8, 2019 · 0 comments
Open

views-markup: How to use linkGenerator in included templates #214

mariogarcia opened this issue Dec 8, 2019 · 0 comments

Comments

@mariogarcia
Copy link

Versions

  • grails: 4.0.1
  • views-markup: 2.0.0.RC2

Context

I would like to use markup templates to render html views instead of using gsp pages. When playing a little bit with templates I came up with an example.

  • Controller providing some model objects
  • Markup view rendered using a custom layout which requires a linkGenerator to resolve resources such as css stylesheets and declaring model objects to use
  • The same view is including some other templates that require linkGenerator to create links

Controller

package org.proto

class SomethingController {

    static class Person {
        Long id
        String name
        Integer age
    }

    def index() {
        render(
            view: 'index',
            model: [
                totalCount: 10,
                people: [
                    new Person(id: 1, name: 'John', age: 32),
                    new Person(id: 2, name: 'Peter', age: 34)
                ]
            ]
        )
    }
}

views/something/index.gml

Declaring model objects in here makes them available to included templates which is the expected behavior. Although I'm not creating any link here, I've checked that it's possible to use Link generator here (via this.g.link and this.g.resource).

import org.proto.SomethingController

model {
    Integer totalCount
    List<SomethingController.Person> people
}

layout 'layouts/custom.gml', title: 'Layout example', bodyContents: contents {
    p "Showing $totalCount rows"
    table {
        include(template: 'something/_thead.gml')
        include(template: 'something/_tbody.gml')
    }
}

views/layouts/custom.gml (fails)

However here, calls to this.g.resource fail because linkGenerator is null.

yieldUnescaped '<!DOCTYPE html>'
html(lang:'en') {
    head {
        meta('http-equiv':'"Content-Type" content="text/html; charset=utf-8"')
        link(rel: 'icon', href:"favicon.ico", type:"image/x-ico")
        link(
            rel: 'stylesheet',
            type: 'text/css',
            href: this.g.resource(dir: 'assets', file: 'main.css')
        )
        title(title)
    }
    body {
        header {
            h1("$title")
        }
        section {
            bodyContents()
        }
        footer {
            yield "footer"
        }
    }
}

views/something/_thead.gml

Obviously works as expected because it doesn't use anything special

thead {
    tr {
        th('ID')
        th('Name')
        th('Description')
    }
}

views/something/_tbody.gml (fails)

As it happened to custom.gml calls to this.g.link didn't work either because linkGenerator is null.

import org.proto.SomethingController

tbody {
    people.each { SomethingController.Person person ->
        tr {
            td(person.id)
            td {
                a(href: "${this.g.link(controller: 'plan', action: 'show', id: person.id)}") {
                    yield "${person.name}"
                }
            }
            td(person.age)
        }
    }
}

Problem

My first impression is that although you can access to the link generator at the top level view, you can't in any of the included, nested templates.

Desired behavior

To be capable of accessing main view link generator from any nested/included templates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant