”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 使用 Twig 通过 PHP 渲染 Markdown

使用 Twig 通过 PHP 渲染 Markdown

发布于2024-11-08
浏览:581

Using Twig for rendering Markdown with PHP

Twig 是使用 Symfony 开发 Web 应用程序时渲染 HTML 的首选模板引擎。
然而,Twig 的灵活性不仅仅限于生成 HTML 页面。它可以成为跨多个渠道交付内容的强大工具,例如生成 Markdown 文件、JSON 输出,甚至纯文本,所有这些都来自同一组内容。

这种适应性允许您为不同的渠道创建内容。

您可以使用 Twig 生成 HTML、Markdown、JSON、文本等

用例:使用 Symfony 获取并渲染配方为 Markdown

在此示例中,我们使用 Symfony 的 HTTP 客户端从外部 API (https://dummyjson.com/recipes/1) 获取配方,并使用 Twig 将其呈现为 Markdown 文档。
这种方法展示了如何结合 Symfony 强大的包(例如用于外部数据检索的 Symfony HTTP 客户端和用于渲染视图的 Twig)来跨多个渠道交付内容,例如命令行工具中的 Markdown 报告。

我们要构建的命令/脚本从 API 中获取食谱数据(标题、描述、成分和说明),对其进行处理,然后使用 Twig 以结构化 Markdown 格式输出内容。这个实际用例说明了如何在 Web 模板之外使用 Twig,使其能够生成各种格式的内容。

所以,我们将使用:

  • Symfony Console 用于构建命令行工具的组件 https://symfony.com/doc/current/components/console.html
  • Symfony HTTP 客户端 https://symfony.com/doc/current/http_client.html 用于获取和使用 HTTP API
  • Symfony Twig https://twig.symfony.com/doc/3.x/intro.html#installation 用于渲染数据
  • 菜谱API:我们将选择一个“虚拟”菜谱 https://dummyjson.com/recipes/1 来展示和演示检索结构化 JSON 并将其转换为 Markdown 文件的过程.

安装必要的 Symfony 组件

确保您已安装 HTTP 请求和创建命令所需的组件:

composer require symfony/http-client symfony/console twig/twig

创建 Symfony 命令

首先,让我们创建一个新的 Symfony 命令。

如果您想了解有关如何使用 Symfony Command 组件创建命令行工具的更多信息,我写了一篇关于此的具体文章:https://dev.to/robertobutti/building-a-command-line-tool -with-php-and-symfony-console-4n6g

命令类,通常进入 src/Commands 目录。

# create a new empty directory
mkdir -p src/Commands
# create a new empty file
touch src/Commands/FetchRecipeCommand.php

命令类(例如,src/Commands/FetchRecipeCommand.php):

setName('recipe')
            ->setDescription('Prints a recipe in Markdown')
            ->setHelp('This command prints a simple recipe in Markdown.');
        // Step 1: loading the Twig environment
        $loader = new \Twig\Loader\FilesystemLoader(__DIR__ . '/../resources/views');
        $twig = new \Twig\Environment(
            $loader,
            // Optional: Enable caching for better performance
            /*[
                'cache' => __DIR__ . '/../../cache',
            ]*/
        );

        $this->twig = $twig;
        parent::__construct();
    }

    protected function configure()
    {
        $this->setDescription('Fetches a recipe from an API and renders it as Markdown');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        // Step 2: Initialize the HTTP client and fetch the recipe
        $client = HttpClient::create();
        $response = $client->request('GET', 'https://dummyjson.com/recipes/1');

        // Step 3: obtain the array of info
        $recipeData = $response->toArray();

        // Step 4: Render the template using Twig, returning a string
        $markdownOutput = $this->twig->render('recipe.md.twig', $recipeData);

        // Step 5: Output the generated Markdown
        $output->writeln($markdownOutput);

        return Command::SUCCESS;
    }
}

以下是 FetchRecipeCommand 示例中每个步骤的详细说明。

逐步细分

第1步:加载twig环境

要在典型的 Web 上下文之外使用 Twig,例如在 PHP 命令行工具中,您首先需要通过 Twig\Environment 类手动初始化它。以下是控制台命令中 Twig 设置的示例:

$loader = new \Twig\Loader\FilesystemLoader(__DIR__ . '/../resources/views');
$twig = new \Twig\Environment(
    $loader,
    // Optional: Enable caching for better performance
    /*[
        'cache' => __DIR__ . '/../../cache',
    ]*/
);
$this->twig = $twig;

解释:

  • twig 环境是通过创建 FilesystemLoader 来初始化的,该 FilesystemLoader 告诉 Twig 在哪里可以找到模板。本例指向存储 Twig 模板的 src/resources/views 文件夹。
  • 然后,$twig 环境被实例化并负责渲染模板。可以启用可选缓存,通过存储预编译模板来提高性能。
  • 最后将初始化的$twig环境赋值给$this->twig供以后使用(在execute()方法中)。

第 2 步:初始化 HTTP 客户端并获取配方

$client = HttpClient::create();
$response = $client->request('GET', 'https://dummyjson.com/recipes/1');

解释:

  • Symfony HTTP 客户端是使用 HttpClient::create() 方法创建的,该方法允许命令执行 HTTP 请求。
  • 要获取菜谱,request() 方法会对指定的 URL (https://dummyjson.com/recipes/1) 执行 GET 请求。
  • API 返回存储在 $response 变量中的 JSON 响应。

第三步:获取信息数组

$recipeData = $response->toArray();

解释:

  • toArray() 方法将来自 API 的 JSON 响应转换为 PHP 数组。该数组包含食谱的数据(例如名称、成分、说明),这些数据将用于在下一步中填充 Twig 模板。

第四步:使用Twig渲染模板

$markdownOutput = $this->twig->render('recipe.md.twig', $recipeData);

解释:

  • Twig 环境的 render() 方法生成 Markdown 输出。它从 src/resources/views 文件夹加载模板 (recipe.md.twig)。
  • 从 API 获取的菜谱数据 ($recipeData) 被传递到模板中,它将替换菜谱名称、成分和说明等占位符,创建一个完全格式化的 Markdown 文件。
  • 渲染后的 Markdown 内容(render() 方法返回的字符串)存储在 $markdownOutput 变量中。

第 5 步:为生成的 Markdown 生成输出

$output->writeln($markdownOutput);

解释:

  • 最终的 Markdown 内容使用 $output->writeln() 方法打印到控制台。该方法将字符串输出到控制台,允许用户以 Markdown 格式查看格式化的菜谱(最终,您可以将输出重定向到 shell 中的文件中)。

创建启动文件

您必须创建一个启动文件以允许用户直接从 shell 启动您的 Symfony 命令。 (在本文中,我们不是创建 Symfony 应用程序;我们正在使用 Symfony 包构建 PHP 脚本。)
在项目目录中,您有composer.json文件和src目录,您可以创建一个my-app文件。

#!/usr/bin/env php
setDefaultCommand("recipe");

$app->add(new FetchRecipeCommand());


$app->run();

要正确使用命名空间和类,请务必在composer.json 文件中设置自动加载部分:

{
    "require": {
        "symfony/http-client": "^7.1",
        "symfony/console": "^7.1",
        "twig/twig": "^3.14"
    },
    "autoload": {
        "psr-4": {
            "MyExample\\": "src/"
        }
    }
}

如果您更改自动加载部分,我建议转储自动加载文件:

composer dump-autoload

现在,您必须创建 Twig 模板/视图来呈现 API 检索到的数据。

为菜谱创建一个 Twig 模板/视图

接下来,创建一个 Twig 模板/视图以以 Markdown 格式呈现配方。
该模板应位于视图目录中(例如,src/resources/view/recipe.md.twig)。

# Recipe: {{ name }}

- Preparation time: {{ prepTimeMinutes }} minutes
- Cooking time {{ cookTimeMinutes }} minutes
- Difficulty level: {{ difficulty }}
- Cuisine: {{ cuisine }}
- Servings {{ servings }} people, with {{ caloriesPerServing }} calories per person

## Ingredients:

{% for ingredient in ingredients %}
- {{ ingredient }}
{% endfor %}

## Instructions:

{% for instruction in instructions %}
- {{ instruction }}
{% endfor %}

Enjoy!

此 Twig 视图文件将以 Markdown 格式呈现菜谱,其中包含菜谱名称、成分和说明部分。

运行命令

要执行命令,请在终端中运行以下命令:

php my-app

如果您有多个命令,您可以启动:

php m-app recipe

查看所有可用命令:

php my-app list

结论

通过这种方法,您可以使用 Symfony 的 HTTP 客户端轻松地从外部 API 检索数据、处理响应并使用 Twig 以结构化格式呈现输出。在本例中,该命令将配方输出为 Markdown,但此技术可以适用于您需要处理的任何其他内容或数据类型。
享受你的食谱!

版本声明 本文转载于:https://dev.to/robertobutti/using-twig-for-rendering-markdown-with-php-2d24?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何监控 Guzzle Http 客户端 – PHP 快速提示
    如何监控 Guzzle Http 客户端 – PHP 快速提示
    Guzzle 是一款流行的 PHP HTTP 客户端,可以轻松发送 HTTP 请求和创建 Web 服务库。最流行的 PHP 框架提供了内部 Http Client 服务,它们只是 Guzzle Http Client 的定制实现: Laravel Http 客户端 Symfony Http 客户端 ...
    编程 发布于2024-11-08
  • 为什么 Python 在方法中需要显式的“Self”参数?
    为什么 Python 在方法中需要显式的“Self”参数?
    揭秘Python方法中的“Self”参数与某些编程语言不同,对象引用是用“this”关键字隐式定义的, Python 要求在方法定义中显式包含“self”参数。这种设计决策提出了一个问题:它是故意的还是实现限制的问题。在 Python 中,“self”参数显式地建立了方法与其类实例之间的关系。它提供...
    编程 发布于2024-11-08
  • 使用 Gin/Golang 时如何处理空请求主体:绑定和调试技术指南
    使用 Gin/Golang 时如何处理空请求主体:绑定和调试技术指南
    Gin/Golang 中请求正文为空使用 Gin 处理 POST 请求时,偶尔可能会遇到请求正文显示为空的问题是空的。这可能会令人沮丧,尤其是当您希望从客户端接收数据时。此问题的一个常见原因是尝试直接打印正文。Gin 将请求正文表示为接口类型 ReadCloser。但打印该接口的字符串值并不会泄露实...
    编程 发布于2024-11-08
  • Python 列表理解
    Python 列表理解
    Python 最酷的事情之一是列表推导式如何让在一行代码中创建和操作列表变得非常容易。列表理解是一种通过转换和过滤现有列表中的元素来构建新列表的简洁方法。这个特性是 Python 使代码更具可读性和高效性的众多方法之一,对于初学者来说是一个很好的学习工具。在这里阅读更多示例...... 奥利弗 |图...
    编程 发布于2024-11-08
  • 如何在 Gin 中组织路由:分组路由定义指南?
    如何在 Gin 中组织路由:分组路由定义指南?
    如何在 Gin 中组织路由为了避免路由定义使主文件混乱,您可以将路由分组到单独的文件中。这种方法可以实现更好的代码组织和可维护性。要创建嵌套路由分组,您可以将路由器变量存储在结构体或全局变量中。然后,各个文件可以将处理程序添加到此共享路由器实例。示例实现routes.gopackage app im...
    编程 发布于2024-11-08
  • Leetcode链表问题
    Leetcode链表问题
    反向链表(LeetCode #206) 难度:简单 概念:迭代和递归方法。 合并两个排序列表 (LeetCode #21) 难度:简单 概念:链表遍历和合并技术。 从列表末尾删除第 N 个节点 **(LeetCode #19) **难度:中等 概念:两指针技术(慢指针和快指针)。 链表循环 **(...
    编程 发布于2024-11-08
  • 如何在 C++ 容器中存储异构对象:boost::any 或自定义实现?
    如何在 C++ 容器中存储异构对象:boost::any 或自定义实现?
    在 C 容器中存储异构对象C 容器通常需要同质元素,这意味着它们只能保存单一类型的对象。但是,在某些情况下,您可能需要一个可以容纳混合数据类型的容器。本文探讨了如何使用 boost::any 库和自定义方法来实现此目的。使用 boost::anyboost::any 是一个模板类可以容纳任何 C 类...
    编程 发布于2024-11-08
  • 使用 Pandas 掌握数据分析:从数据中释放洞察力
    使用 Pandas 掌握数据分析:从数据中释放洞察力
    数据分析是数据科学的核心,Python 的 Pandas 库是一个强大的工具,可以使这项任务变得更轻松、更高效。无论您使用简单的电子表格还是大型数据集,Pandas 都可以让您像专业人士一样灵活地操作、分析和可视化数据。在本文中,我们将深入探讨 Pandas 的基础知识,涵盖从数据操作到高级分析技术...
    编程 发布于2024-11-08
  • 最佳免费开源图标库 4
    最佳免费开源图标库 4
    In 2024, finding the best free icon library can significantly enhance the visual appeal of your websites, apps, or digital projects. Whether you're a ...
    编程 发布于2024-11-08
  • React Part 组件、State 和 Props 入门
    React Part 组件、State 和 Props 入门
    欢迎回到我们的 React.js 之旅!在上一篇文章中,我们介绍了 React 的基础知识,强调了它作为构建动态用户界面的库的优势。今天,我们将深入探讨创建 React 应用程序所必需的三个基本概念:组件、状态和属性。让我们详细探讨这些概念! 什么是 React 组件? React ...
    编程 发布于2024-11-08
  • 如何利用原生 ES6 Promises 有效地链接异步 jQuery 函数?
    如何利用原生 ES6 Promises 有效地链接异步 jQuery 函数?
    JavaScript 的互操作性承诺实现异步 jQuery 函数的高效链接链接异步 jQuery 函数时,通常需要避免 jQuery 的内置函数Promises 功能并使用原生 ES6 Promises 代替。这种互操作性允许 jQuery 操作和您想要的 Promise 实现之间的无缝集成。使用 ...
    编程 发布于2024-11-08
  • 在 Python 中使用 ElementTree 的“find”和“findall”方法时如何忽略 XML 命名空间?
    在 Python 中使用 ElementTree 的“find”和“findall”方法时如何忽略 XML 命名空间?
    在 ElementTree 的“find”和“findall”方法中忽略 XML 命名空间使用 ElementTree 模块解析和定位 XML 文档中的元素时,命名空间会带来复杂性。下面介绍了如何在 Python 中使用“find”和“findall”方法时忽略命名空间。当 XML 文档包含命名空间...
    编程 发布于2024-11-08
  • Bitbucket 综合指南:功能、集成和最佳实践
    Bitbucket 综合指南:功能、集成和最佳实践
    Bitbucket简介 Bitbucket 是 Atlassian 旗下基于 Git 的源代码存储库托管服务,以其强大的集成能力和强大的协作功能而闻名。它适合各种规模的团队,提供可简化开发工作流程、提高生产力并确保安全代码管理的解决方案。无论您是小型团队还是大型企业的一部分,Bitbucket 都...
    编程 发布于2024-11-08
  • 如何在 Python 中用逗号连接列表中的字符串?
    如何在 Python 中用逗号连接列表中的字符串?
    从列表中用逗号连接字符串将字符串列表映射到逗号分隔的字符串是编程中的常见任务。可以采用各种方法来实现此目标,每种方法都有自己的优点和缺点。一种流行的方法是将 join 方法与映射函数结合使用。此方法需要创建一个中间字符串,用作各个字符串之间的分隔符。例如:my_list = ['a', 'b', '...
    编程 发布于2024-11-08
  • 如何处理 AngularJS 应用程序中的锚点哈希链接?
    如何处理 AngularJS 应用程序中的锚点哈希链接?
    AngularJS 中的锚点哈希处理使用锚点浏览网页是一种常见的做法,特别是对于具有多个部分的长页面。然而,在 AngularJS 应用程序中,锚链接处理可能会出现问题。当单击 AngularJS 中的锚链接时,默认行为是拦截单击并将用户重定向到不同的页面。为了解决这个问题,AngularJS 提供...
    编程 发布于2024-11-08

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3