如何在html脚本中调用thymeleaf自定义方言

How to call thymeleaf custom dialect in html script

提问人:Nixen85 提问时间:10/27/2023 最后编辑:Nixen85 更新时间:11/4/2023 访问量:188

问:

所以基本上我尝试使用 thymeleaf 使用 ld+json 构建动态模式。为了检索相应页面的 url,我们设置了一个自定义处理器:

public class QuackUrlAttributeTagProcessor extends AbstractAttributeTagProcessor {
    private static final String ATTR_NAME = "quackToHref";
    private static final int PRECEDENCE = 10000;

    @Autowired
    private ApplicationPropertyAccess applicationProperties;

    /**
     * Constructs a new processor.
     *
     * @param dialectPrefix the prefix to use if not the standard defined by the dialect
     */
    public QuackUrlAttributeTagProcessor(final String dialectPrefix) {
        super(
            TemplateMode.HTML, // This processor will apply only to HTML mode
            dialectPrefix,     // Prefix to be applied to name for matching
            null,              // No tag name: match any tag name
            false,             // No prefix to be applied to tag name
            ATTR_NAME,         // Name of the attribute that will be matched
            true,              // Apply dialect prefix to attribute name
            PRECEDENCE,        // Precedence (inside dialect's precedence)
            true);             // Remove the matched attribute afterwards
    }

    /**
     * Performs the actual task of the processor. This will use quack data to construct an Url path.
     */
    @Override
    protected void doProcess(final ITemplateContext context, final IProcessableElementTag tag,
            final AttributeName attributeName, final String attributeValue,
            final IElementTagStructureHandler structureHandler) {
        IEngineConfiguration configuration = context.getConfiguration();
        IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration);
        IStandardExpression expression = parser.parseExpression(context, attributeValue);

        Quack quack = (Quack)expression.execute(context);
        String url = QuackManager.buildUrlPath(quack);

        structureHandler.setAttribute("href", applicationProperties.getFrontendBaseUrl() + url);
    }
}

自定义方言:

public class XContDialect extends AbstractProcessorDialect implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    /**
     * Constructor that will define the name of the Dialect.
     */
    public XConDialect() {
        super("XConsult Dialect", "xc", 1000);
    }

    /**
     * Initialise the dialect's processors.
     *
     * Note the dialect prefix is passed here because, although "xc" is set to be the dialect's prefix in the
     * constructor, that only works as a default, and at engine configuration time the user might have chosen
     * a different prefix to be used.
     */
    public Set<IProcessor> getProcessors(final String dialectPrefix) {
        final Set<IProcessor> processors = new HashSet<IProcessor>();

        QuackUrlAttributeTagProcessor processor = new QuackUrlAttributeTagProcessor(dialectPrefix);
        AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
        factory.autowireBean(processor);

        processors.add(processor);
        return processors;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

有了这个,我可以在html模板中添加属性,如下所示:

<html xmlns:th="http://www.thymeleaf.org" xmlns:xc="http://www.example.de">

 <link rel="canonical" xc:quackToHref="${quack}" />

正确设置 href 属性。现在 ld+json 脚本如下所示:

<script type="application/ld+json">

    /*<![CDATA[*/

    {
      "@context": "https://schema.org",
      "@graph": [
        {
          "@type": "Article",
          "url": "[[xc:quackToHref="${quack}"]]",
          "isPartOf": { "@id": "test" },
          "author": {
            "name": "[[${article.nickname}]]",
            "@id": "https://example.de/profile/[[${article.authorId}]]"
          },          
        },
       
        ]
      }

    /*]]>*/

  </script>

是什么引发了错误:

Caused by: org.attoparser.ParseException: Could not parse as expression: "xc:quackToHref="${quack}" (template: "articlequack" - line 38, col 22)

显然,无法在脚本中调用自定义处理器。有谁知道如何在 CDATA 中获取 url?

java html json thymeleaf schema.org

评论

0赞 Anish B. 10/30/2023
你能说出你对嘎嘎使用什么依赖关系吗?我妨碍了解决这个问题?
0赞 Nixen85 11/1/2023
到目前为止,我发现唯一有效的解决方案是通过以下方式直接调用服务。我想我尝试了大约 1k 个字符组合,我只是没有找到分别在 javascript 或 ld+json 中调用该方法的方法。https://mysite.de[[${T(de.my.service.QuackManager).buildUrlPath(quack)}]]quackToHref

答:

0赞 Metroids 10/27/2023 #1

如果要在文本模板模式下使用属性,语法应如下所示:

[# xc:quackToHref="${quack}" /]

评论

0赞 Nixen85 10/28/2023
这不会被解析,而只是在 json 中返回字符串 [# xc:quackToHref=“${quack}” /]。xc:quackToHref 只是在 html 标签中使用时被解析,而不是在脚本中解析
0赞 Metroids 10/28/2023
如果您将 th:inline=“javascript” 添加到您的脚本标签中,它会起作用吗? ?<script type="application/ld+json" th:inline="javascript">
0赞 Nixen85 10/28/2023
在这种情况下,我只是没有得到任何返回值(),也看不到在我的java日志中调用了该方法。因此,我可能需要为 CDATA 设置另一个处理器,如此处所述 thymeleaf.org/doc/tutorials/3.0/......@id": ,
0赞 Swapnil 10/30/2023 #2

试试这个

<script type="application/ld+json">

    {
      "@context": "https://schema.org",
      "@graph": [
        {
          "@type": "Article",
          "url": "[[${applicationProperties.frontendBaseUrl}]]${quack}", 
          "isPartOf": { "@id": "test" },
          "author": {
            "name": "[[${article.nickname}]]",
            "@id": "https://example.de/profile/[[${article.authorId}]]"
          }         
        }
      ]
    }

   

</script>
  • 确保在模板中使用 applicationProperties.frontendBaseUrl 变量的位置可以访问该变量。
  • 正确使用 Thymeleaf 表达式:检查您是否在模板中正确使用 Thymeleaf 表达式,例如 或[[...]]${...}.

试试这个,如果没有解决,请告诉我这里的评论..

评论

0赞 Nixen85 10/30/2023
这将返回“console.log(<!DOCTYPE HTML>“ 抛出以下错误 Servlet.service() for servlet [dispatcherServlet] in context with path [] thrown exception [Request processing failed; nested exception isorg.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/articlequack.html]")] with root cause org.springframework.expression.spel.SpelEvaluationException: EL1011E: Method call: Attempted to call method getFrontendBaseUrl() on null context object
-2赞 Harsha Kidambi 11/4/2023 #3

若要在 HTML 模板中使用自定义 Thymeleaf 方言,需要在项目中包含该方言,对其进行配置,然后在 HTML 文件中使用它。以下是在 HTML 脚本中调用自定义 Thymeleaf 方言的步骤:

  1. 将自定义方言添加到您的项目中:

    • 首先,您需要通过实现接口来创建自定义 Thymeleaf 方言。这涉及定义方言将处理的自己的处理器、属性或标记。org.thymeleaf.dialect.IDialect
  2. 将 Thymeleaf 配置为使用自定义方言:

    • 在您的项目配置(例如,Spring Boot 应用程序)中,您可以将 Thymeleaf 配置为包含您的自定义方言。下面是如何在 Spring Boot 应用程序或文件中使用自定义方言配置 Thymeleaf 的示例:application.propertiesapplication.yml
    spring.thymeleaf.mode=HTML
    spring.thymeleaf.cache=false
    spring.thymeleaf.enabled=true
    spring.thymeleaf.prefix=classpath:/templates/
    spring.thymeleaf.suffix=.html
    spring.thymeleaf.encoding=UTF-8
    spring.thymeleaf.servlet.content-type=text/html
    spring.thymeleaf.servlet.cache=true
    spring.thymeleaf.servlet.order=1
    spring.thymeleaf.check-template-location=true
    spring.thymeleaf.template-resolver-order=1
    spring.thymeleaf.cache-names=cache
    spring.thymeleaf.dialects.custom-dialect=your.package.CustomDialect
    

    在此示例中,您将通过指定自定义方言的包和类名来配置 Thymeleaf 方言。

  3. 在 HTML 模板中使用自定义方言:

    • 在 HTML 模板中,您现在可以使用自定义方言的功能。例如,如果您的自定义方言添加了自定义属性或标记,则可以按如下方式使用它:
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:custom="http://www.example.com/thymeleaf-custom-dialect">
    <head>
        <title>Custom Dialect Example</title>
    </head>
    <body>
        <div custom:yourAttribute="someValue">Custom Dialect Attribute</div>
        <custom:customTag>Custom Dialect Tag</custom:customTag>
    </body>
    </html>
    

    替换为自定义方言的命名空间 URI。http://www.example.com/thymeleaf-custom-dialect

  4. 生成并运行应用程序:

    • 在 HTML 模板中配置和使用自定义方言后,生成并运行应用程序。自定义方言的功能将在渲染期间应用于 Thymeleaf 模板。

确保在应用程序中正确实现和注册自定义方言,使其按预期工作。此外,请确保在 HTML 模板中使用正确的命名空间和语法来调用自定义方言的功能。