refactor: exclude post preview page from data tracking (#7582)

What type of PR is this?  
/kind bug  
/area core  
/milestone 2.21.x

What this PR does / why we need it:  
Prevents published post view counts from being incorrectly increased when previewing posts in the admin panel.

Previously, the preview mode would load the tracking script, which resulted in inflated view counts. This PR adds a condition to detect preview mode and disables the tracking logic to avoid counting views for unpublished content.

Does this PR introduce user-facing changes?
```release-note
文章预览页面不再统计访问数据
```
pull/7613/head
Golden Supreme Salted Fish 2025-07-04 12:33:41 +08:00 committed by GitHub
parent a6322fa023
commit 79226998d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 16 additions and 0 deletions

View File

@ -1,5 +1,6 @@
package run.halo.app.theme.dialect;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.thymeleaf.context.ITemplateContext;
@ -21,6 +22,8 @@ import run.halo.app.infra.utils.PathUtils;
@Component
public class HaloTrackerProcessor implements TemplateHeadProcessor {
public static final String SKIP_TRACKER = HaloTrackerProcessor.class.getName() + ".SKIP_TRACKER";
private final ExternalUrlSupplier externalUrlGetter;
public HaloTrackerProcessor(ExternalUrlSupplier externalUrlGetter) {
@ -30,6 +33,12 @@ public class HaloTrackerProcessor implements TemplateHeadProcessor {
@Override
public Mono<Void> process(ITemplateContext context, IModel model,
IElementModelStructureHandler structureHandler) {
// Check if tracker should be skipped
var isSkip = (Boolean) context.getVariable(SKIP_TRACKER);
if (BooleanUtils.isTrue(isSkip)) {
return Mono.empty();
}
final IModelFactory modelFactory = context.getModelFactory();
return Mono.just(getTrackerScript(context))
.filter(StringUtils::isNotBlank)

View File

@ -25,6 +25,7 @@ import run.halo.app.infra.AnonymousUserConst;
import run.halo.app.infra.exception.NotFoundException;
import run.halo.app.theme.DefaultTemplateEnum;
import run.halo.app.theme.ViewNameResolver;
import run.halo.app.theme.dialect.HaloTrackerProcessor;
import run.halo.app.theme.finders.PostPublicQueryService;
import run.halo.app.theme.finders.SinglePageConversionService;
import run.halo.app.theme.finders.vo.ContributorVo;
@ -81,6 +82,9 @@ public class PreviewRouterFunction {
.flatMap(postVo -> {
String template = postVo.getSpec().getTemplate();
Map<String, Object> model = ModelMapUtils.postModel(postVo);
// Mark as preview mode for downstream view processing
request.exchange().getAttributes()
.put(HaloTrackerProcessor.SKIP_TRACKER, Boolean.TRUE);
return viewNameResolver.resolveViewNameOrDefault(request, template,
DefaultTemplateEnum.POST.getValue())
.flatMap(templateName -> ServerResponse.ok().render(templateName, model));
@ -148,6 +152,9 @@ public class PreviewRouterFunction {
.switchIfEmpty(Mono.error(() -> new NotFoundException("Single page not found.")))
.flatMap(singlePageVo -> {
Map<String, Object> model = ModelMapUtils.singlePageModel(singlePageVo);
// Mark as preview mode for downstream view processing
request.exchange().getAttributes()
.put(HaloTrackerProcessor.SKIP_TRACKER, Boolean.TRUE);
String template = singlePageVo.getSpec().getTemplate();
return viewNameResolver.resolveViewNameOrDefault(request, template,
DefaultTemplateEnum.SINGLE_PAGE.getValue())