# PoExtractor **Repository Path**: smartent/po-extractor ## Basic Information - **Project Name**: PoExtractor - **Description**: 从C#、F#抽取国际化文本字符串到 .PO、.POT 文件 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-09-08 - **Last Updated**: 2026-10-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OrchardCoreContrib.PoExtractor ![Orchard Core Contrib](images/OCC.png) `OrchardCoreContrib.PoExtractor` 是一个分布式为 dotnet 全局工具,用于从 C# 和 VB 代码、Razor 模板和 Liquid 模板中提取可翻译字符串到 POT(可移植对象模板)文件。它设计为遵循 [OrchardCore](https://github.com/OrchardCMS/OrchardCore) 项目中使用的约定。 ## 安装 使用以下命令安装: ```powershell dotnet tool install --global OrchardCoreContrib.PoExtractor ``` ## 使用方法 ```powershell extractpo <输入路径> <输出路径> [-l|--language {"C#"|"VB"}] [-t|--template {"razor"|"liquid"}] ``` ### 描述 从指定输入路径的项目中提取所有可翻译字符串,并将生成的 POT 文件保存到指定的输出路径。它为每个项目创建一个 POT 文件。这包括 liquid 视图。 ### 参数 - **`输入路径`** 输入目录的路径,该路径下的所有项目都将被处理。 - **`输出路径`** 生成 POT 文件的目录路径。 ### 选项 - **`-l|--language {C#|VB}`** 指定要提取可翻译字符串的代码语言。默认:`C#` 语言 - **`-t|--template {"razor"|"liquid"}`** 指定要提取可翻译字符串的模板引擎。默认:`Razor` 和 `Liquid` 模板。 - **`-p|--plugin {CSX 文件路径或 URL}`** 指定一个 C# 脚本文件的路径,该文件可以定义进一步的项目处理器。(您可以在此处找到示例脚本 [here](test/OrchardCoreContrib.PoExtractor.Tests/PluginTestFiles/BasicJsonLocalizationProcessor.csx)。)这可用于处理上述选项不支持的代码语言或模板引擎的本地化。您可以在一次调用中使用多个这些开关来同时加载多个插件。如果参数以 `https://` 开头,则将其视为网络 URL,并从该地址下载脚本到内存中执行,而不是本地文件。 执行插件时,所有 _OrchardCoreContrib.PoExtractor_ 程序集都会自动加载,并定义了两个全局变量: - `List ProjectProcessors`:将您的自定义 `IProjectProcessor` 实现类型的实例添加到此列表中。 - `List ProjectFiles`:在不太可能的情况下,您必须添加新的项目文件类型(如 _.fsproj_),请将项目文件路径添加到此列表中。 > [!提示] > 您不能在脚本文件中导入 NuGet 包,但可以使用 `#r "path/to/package.dll"` 指令导入本地 DLL 文件。路径可以相对于脚本文件的位置,因此您可以从要提取的项目构建目录中导入包。如果您使用 MSBuild 作为后构建操作启动工具,这可能特别有用。(对于通过 URL 加载的远程脚本,路径可以相对于当前工作目录。)例如: > > ```csharp > #r "src/Modules/OrchardCore.Commerce/bin/Debug/net8.0/OrchardCore.Commerce.dll" > using OrchardCore.Commerce.Constants; > Console.WriteLine("Imported resource name: {0}", ResourceNames.ShoppingCart); > ``` ## 卸载 ```powershell dotnet tool uninstall --global OrchardCoreContrib.PoExtractor ``` ## 限制 OrchardCoreContrib.PoExtractor 假设代码遵循以下约定: * `IStringLocalizer` 或派生类通过名为 `S` 的字段访问(这是 Orchard Core 中使用的约定) * `IHtmlLocalizer` 或派生类通过名为 `H` 的字段访问(这是 Orchard Core 中使用的约定) * `IStringLocalizer` 或 `IHtmlLocalizer` 通过名为 `T` 的字段访问(这是 Orchard Core 中使用的较旧约定) * Liquid 模板使用名为 `t` 的过滤器(这是 Fluid 中使用的约定) * 对于 C# 或 VB 代码,可本地化字符串的上下文是包含类的完整名称(带命名空间) * 对于 Razor 模板,可本地化字符串的上下文是到视图的点分隔相对路径 * 对于 Liquid 模板,可本地化字符串的上下文是到模板的点分隔相对路径 ## 示例 C# 代码: ```csharp namespace OrchardCore.ContentFields.Fields { public class LinkFieldDisplayDriver : ContentFieldDisplayDriver { private IStringLocalizer S; public LinkFieldDisplayDriver(IStringLocalizer localizer) { S = localizer; } public override async Task UpdateAsync(LinkField field, IUpdateModel updater, UpdateFieldEditorContext context) { bool modelUpdated = await updater.TryUpdateModelAsync(field, Prefix, f => f.Url, f => f.Text); if (modelUpdated) { var settings = context.PartFieldDefinition.Settings.ToObject(); if (settings.Required && String.IsNullOrWhiteSpace(field.Url)) { updater.ModelState.AddModelError(Prefix, S["The url is required for {0}.", context.PartFieldDefinition.DisplayName()]); } } return Edit(field, context); } } } ``` VB 代码: ```vb Namespace OrchardCore.Modules.GreetingModule Public Class Greeting private readonly S As IStringLocalizer(Of Greeting) Public Sub New(ByVal localizer As IStringLocalizer(Of Greeting)) S = localizer End Sub Public Sub Saulation(byVal name As String) Console.WriteLine(S("Hi {0} ...", name)) End Sub End Class End Namespace ``` Razor 视图: ```html @model OrchardCore.ContentFields.ViewModels.EditLinkFieldViewModel
``` Liquid 模板: ```html div class="page-heading">

{{ "Page Not Found" | t }}

/div> ``` 生成的 POT 文件: ``` #: OrchardCore.ContentFields\Drivers\LinkFieldDriver.cs:59 #. updater.ModelState.AddModelError(Prefix, T["The url is required for {0}.", context.PartFieldDefinition.DisplayName()]); msgctxt "OrchardCore.ContentFields.Fields.LinkFieldDisplayDriver" msgid "The url is required for {0}." msgstr "" #: OrchardCore.Modules.GreetingModule\Greeting.vb:94 #. Console.WriteLine(S("Hi {0} ...", name)) msgctxt "OrchardCore.Modules.GreetingModule.Greeting" msgid "Hi {0} ..." msgstr "" #: OrchardCore.ContentFields\Views\LinkField.Edit.cshtml:32 #. msgctxt "OrchardCore.ContentFields.Views.LinkField.Edit" msgid "Link text" msgstr "" #: TheBlogTheme\Views\Shared\NotFound.liquid:0 msgctxt "TheBlogTheme.Views.Shared.NotFound" msgid "Page Not Found" msgstr "" ``` ## 致谢 **PoExtractor** https://github.com/lukaskabrt/PoExtractor Lukas Kabrt