Как Grails знает, как применить "макет" к страницам, которые он отображает?
Я читал книгу "Окончательное руководство к Grails" (Rocher/Brown), а в главе 04 эта загадочная вещь, называемая "макет", появилась просто без объяснений. (И там нет "макета" в индексе. Насколько я знаю, он никогда не объяснял.)
Как система знает, чтобы "наследовать" страницы из layout/main.gsp? Нет ничего о "макетах" в индексе, и он, кажется, только что появился.
В своем примерном приложении, на простом сайте магазина, сопоставления URL-адресов для /homepage говорят
"/"(controller:"store")
и сохранить пустой контроллер хранилища "index"
package com.g2one.gtunes
class StoreController {
def index = {
}
}
просто сообщает об этом для отображения store/index.gsp
В магазине /index.gsp есть несколько строк HTML; макет не включается в любую директиву
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta name="layout" content="main">
<title>gTunes Store</title>
<g:javascript library="prototype"></g:javascript>
</head>
<body id="body">
<h1>Your online music store and storage service!</h1>
<p>Manage your own library, browse music and purchase new tracks as they become available</p>
</body>
</html>
Когда я запускаю образец, страница, показанная для "/", - это не просто этот простой HTML, это содержимое "layouts/main.gsp" с этой магией, встроенной в нее.
Я не вижу, как информация в layout/main.gsp применяется к странице, как элементы смешиваются. Я следил за книгой за страницей, и эта функциональность просто "появилась" без объяснений.
Ответы
Ответ 1
Тег <meta name="layout" content="main">
содержит макет на странице gsp.
Вы можете просмотреть grails-app/views/layouts/main.gsp
для просмотра и изменения макета. Вы можете скопировать main.gsp
в mymain.gsp
, изменить его, а затем изменить запись макета на странице gsp для ссылки mymain.gsp
вместо main.gsp
и поэкспериментировать с настройкой макета, сохраняя вашу способность легко отменить ваши изменения.
Grails использует sitemesh под обложками (например, использует hibernate и spring) для создания макетов представлений. В каталоге проекта есть файл конфигурации web-app/WEB-INF/sitemesh.xml
. Этот конкретный файл не так полезен, но он ссылается на класс в проекте groovy, если вы хотите глубоко понять, как grails использует sitemesh (это, вероятно, не обязательно).
Ответ 2
Здесь ваша директива:
<meta name="layout" content="main">
main.gsp содержит <g:layoutHead>
и <g:layoutBody>
, где содержимое <head>
и <body>
index.gsp складывается в макет для создания последней страницы.
Ответ 3
Один недавний трюк, который, кажется, работает, если вы назовете свой макет в соответствии с вашим контроллером, он появляется (по крайней мере, в Grails 2.3.4) для автоматического использования этого шаблона.
Например, мой контроллер:
// grails-app/controllers/myapp/HomeController.groovy
package myapp
class HomeController {
def index() {
[ myvar: "Test" ]
}
}
мой макет:
// grails-app/views/layouts/home.gsp
<html>
<head></head>
<body>
<h1>Home</h1>
<g:layoutBody />
</body>
</html>
мой взгляд:
// grails-app/views/home/index.gsp
<p>${ myvar }</p>
отображает исходный макет.
Кроме того, вы можете указать макет для всех своих действий в контроллере следующим образом:
class HomeController {
static layout = "someotherlayout"
// actions will render using grails-app/views/layouts/someotherlayout.gsp
}