mirror of https://github.com/halo-dev/halo
refactor: fill in the name of the rendered template as the template id to the view model (#2626)
#### What type of PR is this? /kind improvement /area core /milestone 2.0 #### What this PR does / why we need it: 渲染模板页面时将被渲染的模板名称填充到试图模型中作为 templateId 为什么需要它: 1. thymeleaf 渲染模板可以使用 fragment,此时在 thymeleaf 的 IElementTagProcessor 等处理器中获取到的 template name不一定是例如 post.html这样的名称 2. 比如渲染文章模板 post.html 而 #2569 计划将要在 theme.yaml 中通过配置允许用户选择文章所渲染的模板,因为无法确定渲染模板的标志,例如有些处理器想在文章页插入 head 这样的需求就需要知道哪个模板是文章页。see also [issuecomment-1215135195](https://github.com/halo-dev/halo/issues/2322#issuecomment-1215135195) 所以目前想到的是通过在 render 时填充一个 templateId 到 view model 中标识模板身份 #### Which issue(s) this PR fixes: Fixes #2621 #### Special notes for your reviewer: how to test it? 见 issue #2621 /cc @halo-dev/sig-halo #### Does this PR introduce a user-facing change? ```release-note 修复设置了文章的 htmlMetas 字段但没有在页面的 head 注入标签的问题 ```pull/2629/head
parent
7c3fc3ac02
commit
3ec7e31cac
|
@ -11,6 +11,7 @@ import org.thymeleaf.processor.element.IElementModelStructureHandler;
|
|||
import reactor.core.publisher.Mono;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.PostFinder;
|
||||
import run.halo.app.theme.router.strategy.ModelConst;
|
||||
|
||||
/**
|
||||
* <p>The <code>head</code> html snippet injection processor for post template.</p>
|
||||
|
@ -31,9 +32,10 @@ public class PostTemplateHeadProcessor implements TemplateHeadProcessor {
|
|||
@Override
|
||||
public Mono<Void> process(ITemplateContext context, IModel model,
|
||||
IElementModelStructureHandler structureHandler) {
|
||||
return Mono.just(context.getTemplateData().getTemplate())
|
||||
.filter(this::isPostTemplate)
|
||||
.map(template -> (String) context.getVariable(POST_NAME_VARIABLE))
|
||||
if (!isPostTemplate(context)) {
|
||||
return Mono.empty();
|
||||
}
|
||||
return Mono.justOrEmpty((String) context.getVariable(POST_NAME_VARIABLE))
|
||||
.map(postFinder::getByName)
|
||||
.doOnNext(postVo -> {
|
||||
List<Map<String, String>> htmlMetas = postVo.getSpec().getHtmlMetas();
|
||||
|
@ -59,7 +61,8 @@ public class PostTemplateHeadProcessor implements TemplateHeadProcessor {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
private boolean isPostTemplate(String template) {
|
||||
return DefaultTemplateEnum.POST.getValue().equals(template);
|
||||
private boolean isPostTemplate(ITemplateContext context) {
|
||||
return DefaultTemplateEnum.POST.getValue()
|
||||
.equals(context.getVariable(ModelConst.TEMPLATE_ID));
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import reactor.core.publisher.Mono;
|
|||
import run.halo.app.infra.SystemConfigurableEnvironmentFetcher;
|
||||
import run.halo.app.infra.SystemSetting;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.router.strategy.ModelConst;
|
||||
|
||||
/**
|
||||
* <p>Global custom head snippet injection for theme global setting.</p>
|
||||
|
@ -39,8 +40,7 @@ public class TemplateGlobalHeadProcessor implements TemplateHeadProcessor {
|
|||
|
||||
// add content head to model
|
||||
String contentHeader = codeInjection.getContentHead();
|
||||
String template = context.getTemplateData().getTemplate();
|
||||
if (StringUtils.isNotBlank(contentHeader) && isContentTemplate(template)) {
|
||||
if (StringUtils.isNotBlank(contentHeader) && isContentTemplate(context)) {
|
||||
model.add(modelFactory.createText(contentHeader + "\n"));
|
||||
}
|
||||
})
|
||||
|
@ -51,8 +51,9 @@ public class TemplateGlobalHeadProcessor implements TemplateHeadProcessor {
|
|||
return fetcher.fetch(SystemSetting.CodeInjection.GROUP, SystemSetting.CodeInjection.class);
|
||||
}
|
||||
|
||||
private boolean isContentTemplate(String template) {
|
||||
// TODO includes custom page template
|
||||
return DefaultTemplateEnum.POST.getValue().equals(template);
|
||||
private boolean isContentTemplate(ITemplateContext context) {
|
||||
String templateId = (String) context.getVariable(ModelConst.TEMPLATE_ID);
|
||||
return DefaultTemplateEnum.POST.getValue().equals(templateId)
|
||||
|| DefaultTemplateEnum.SINGLE_PAGE.getValue().equals(templateId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,8 @@ public class CategoriesRouteStrategy implements ListPageRouteHandlerStrategy {
|
|||
public HandlerFunction<ServerResponse> getHandler() {
|
||||
return request -> ServerResponse.ok()
|
||||
.render(DefaultTemplateEnum.CATEGORIES.getValue(),
|
||||
Map.of("categories", categories()));
|
||||
Map.of("categories", categories(),
|
||||
ModelConst.TEMPLATE_ID, DefaultTemplateEnum.CATEGORIES.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -65,7 +65,8 @@ public class CategoryRouteStrategy implements DetailsPageRouteHandlerStrategy {
|
|||
.render(DefaultTemplateEnum.CATEGORY.getValue(),
|
||||
Map.of("name", name,
|
||||
"posts", postListByCategoryName(name, request),
|
||||
"category", categoryByName(name)));
|
||||
"category", categoryByName(name),
|
||||
ModelConst.TEMPLATE_ID, DefaultTemplateEnum.CATEGORY.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -48,7 +48,8 @@ public class IndexRouteStrategy implements ListPageRouteHandlerStrategy {
|
|||
public HandlerFunction<ServerResponse> getHandler() {
|
||||
return request -> ServerResponse.ok()
|
||||
.render(DefaultTemplateEnum.INDEX.getValue(),
|
||||
Map.of("posts", postList(request)));
|
||||
Map.of("posts", postList(request),
|
||||
ModelConst.TEMPLATE_ID, DefaultTemplateEnum.INDEX.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package run.halo.app.theme.router.strategy;
|
||||
|
||||
/**
|
||||
* Static variable keys for view model.
|
||||
*
|
||||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public enum ModelConst {
|
||||
;
|
||||
public static final String TEMPLATE_ID = "_templateId";
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package run.halo.app.theme.router.strategy;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.method;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.path;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.util.UriUtils;
|
||||
|
||||
public enum PermalinkPredicates {
|
||||
;
|
||||
|
||||
public static RequestPredicate get(String permalink) {
|
||||
return method(HttpMethod.GET).and(path(UriUtils.decode(permalink, UTF_8)));
|
||||
}
|
||||
}
|
|
@ -50,8 +50,12 @@ public class PostRouteStrategy implements DetailsPageRouteHandlerStrategy {
|
|||
model.putAll(pathMatchInfo.getUriVariables());
|
||||
}
|
||||
model.put("post", postByName(name));
|
||||
// used by HaloTrackerProcessor
|
||||
model.put("groupVersionKind", groupVersionKind);
|
||||
model.put("plural", gvk.plural());
|
||||
// used by TemplateGlobalHeadProcessor and PostTemplateHeadProcessor
|
||||
model.put(ModelConst.TEMPLATE_ID, DefaultTemplateEnum.POST.getValue());
|
||||
|
||||
return ServerResponse.ok()
|
||||
.render(DefaultTemplateEnum.POST.getValue(), model);
|
||||
};
|
||||
|
|
|
@ -48,7 +48,10 @@ public class SinglePageRouteStrategy implements DetailsPageRouteHandlerStrategy
|
|||
Map.of("name", name,
|
||||
"groupVersionKind", gvk,
|
||||
"plural", getPlural(),
|
||||
"singlePage", singlePageByName(name)));
|
||||
"singlePage", singlePageByName(name),
|
||||
ModelConst.TEMPLATE_ID, DefaultTemplateEnum.SINGLE_PAGE.getValue()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -65,7 +65,9 @@ public class TagRouteStrategy implements DetailsPageRouteHandlerStrategy {
|
|||
.render(DefaultTemplateEnum.TAG.getValue(),
|
||||
Map.of("name", name,
|
||||
"posts", postList(request, name),
|
||||
"tag", tagByName(name))
|
||||
"tag", tagByName(name),
|
||||
ModelConst.TEMPLATE_ID, DefaultTemplateEnum.TAG.getValue()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,10 @@ public class TagsRouteStrategy implements ListPageRouteHandlerStrategy {
|
|||
public HandlerFunction<ServerResponse> getHandler() {
|
||||
return request -> ServerResponse.ok()
|
||||
.render(DefaultTemplateEnum.TAGS.getValue(),
|
||||
Map.of("tags", tags()));
|
||||
Map.of("tags", tags(),
|
||||
ModelConst.TEMPLATE_ID, DefaultTemplateEnum.TAGS.getValue()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -34,6 +34,7 @@ import run.halo.app.plugin.ExtensionComponentsFinder;
|
|||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.PostFinder;
|
||||
import run.halo.app.theme.finders.vo.PostVo;
|
||||
import run.halo.app.theme.router.strategy.ModelConst;
|
||||
|
||||
/**
|
||||
* Tests for {@link HaloProcessorDialect}.
|
||||
|
@ -128,6 +129,8 @@ class HaloProcessorDialectTest {
|
|||
void contentHeadAndFooterAndPostProcessors() {
|
||||
Context context = getContext();
|
||||
context.setVariable("name", "fake-post");
|
||||
// template id flag is used by TemplateGlobalHeadProcessor
|
||||
context.setVariable(ModelConst.TEMPLATE_ID, DefaultTemplateEnum.POST.getValue());
|
||||
|
||||
List<Map<String, String>> htmlMetas = new ArrayList<>();
|
||||
htmlMetas.add(ImmutableSortedMap.of("name", "post-meta-V1", "content", "post-meta-V1"));
|
||||
|
|
Loading…
Reference in New Issue