使用 Cocoa Webkit 进行国际化显示前修改 HTML 的方法
Way To Modify HTML Before Display using Cocoa Webkit for Internationalization
在 Objective C 中构建 Mac OSX (Cocoa) 应用程序,我使用本机 Webkit 小部件显示本地文件 file://
URL,从此文件夹中拉取:
MyApp.app/Contents/Resources/lang/en/html
一切都很好直到我开始需要德语版本。这意味着我必须将 en/html 复制为 de/html,然后有人用德语措辞替换了 HTML 中的措辞(以及 Javascript 中的一些措辞(例如模态对话框))。工作量很大!
好吧,这似乎是可行的,直到这让我很头疼,我不得不为我需要支持的每种语言不断维护 html 文件夹的多个版本。
然后我想到了...
Why not just replace the phrasing with template tags like %CONTINUE%
and then, before the page is rendered, intercept it and swap it out
with strings pulled from a language plist file?
通过一些API这个widget,是否可以在渲染之前拦截HTML并替换文本?
如果可能的话,它会不会太慢以至于不值得?
或者,您是否建议我做一个策略,即我构建一个生成器,我保留在我的工作站上,它从主模板为我构建每个 HTML 文件夹,然后一旦我从安装应用程序确定用户的语言,我就部署那些已经用我的安装应用程序完成的?
通过大量实验,我发现了一种丑陋的模板制作方式。就像我说的,这是不可取的并且有一些副作用:
您会在第一次 window 加载时看到一个闪光灯。在第一次加载具有 WebKit 小部件的应用程序 window 时,您需要隐藏 window 直到第二次显示页面内容。我猜你必须为此使用 属性。
导航时,每个页面加载两次。几乎不引人注意,但还不够好发展。
我发现 Bootstrap CSS 有一个奇怪的问题,它使我的 table 网格行非常大并且没有正确应用 CSS出于某种奇怪的原因。我也许可以调整 CSS 来解决这个问题。
不幸的是,除了 didFinishLoadForFrame
,我发现没有其他事件可以拦截。但是,到那时,该页面已经下载并呈现了至少一次一微秒。最好在此之前拦截一些事件,我有完整的 HTML,并在显示之前在那里进行交换。我没有找到这样的事件。但是,如果有人发现这样的事件——那可能会使它成为一个很好的模板解决方案。
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
{
DOMHTMLElement * htmlNode =
(DOMHTMLElement *) [[[frame DOMDocument] getElementsByTagName: @"html"] item: 0];
NSString *s = [htmlNode outerHTML];
if ([s containsString:@"<!-- processed -->"]) {
return;
}
NSURL *oBaseURL = [[[frame dataSource] request] URL];
s = [s stringByReplacingOccurrencesOfString:@"%EXAMPLE%" withString:@"ZZZ"];
s = [s stringByReplacingOccurrencesOfString:@"</head>" withString:@"<!-- processed -->\n</head>"];
[frame loadHTMLString:s baseURL:oBaseURL];
}
以上将查看包含%EXAMPLE%
的HTML并将其替换为ZZZ
。
最后,我意识到这是低效的,因为页面闪烁,并且在需要大量替换的长文本上,可能会有一些非常明显的延迟。更好的方法是创建一个编译时生成器。这将创建一个 HTML 文件夹,其中包含 %PARAMETERIZED_TAGS%
而不是英文文本。然后,在你的 "Build Phase" 中创建一个 "Run Script" 来运行你用你想要的任何语言创建的一些 program/script 从所有可用的 lang-[=42= 生成每个 HTML 文件夹] 目录中的文件,其中 XX 是语言代码,如 'en'、'de' 等。它读取 HTML 文件,在 lang-XX.plist 文件,并用该语言的文本替换该文本。这样,编译后,每种语言都有几个 HTML 文件夹,已经在使用翻译后的字符串。这是有效的,因为它允许您有一个单独的 HTML 文件夹来处理您的代码,而不必执行以每种语言创建每个 HTML 文件夹的极其繁琐的过程,也不必保持混乱。编译时生成器会为你做那件事。但是——您必须构建该编译时生成器。
在 Objective C 中构建 Mac OSX (Cocoa) 应用程序,我使用本机 Webkit 小部件显示本地文件 file://
URL,从此文件夹中拉取:
MyApp.app/Contents/Resources/lang/en/html
一切都很好直到我开始需要德语版本。这意味着我必须将 en/html 复制为 de/html,然后有人用德语措辞替换了 HTML 中的措辞(以及 Javascript 中的一些措辞(例如模态对话框))。工作量很大!
好吧,这似乎是可行的,直到这让我很头疼,我不得不为我需要支持的每种语言不断维护 html 文件夹的多个版本。
然后我想到了...
Why not just replace the phrasing with template tags like %CONTINUE% and then, before the page is rendered, intercept it and swap it out with strings pulled from a language plist file?
通过一些API这个widget,是否可以在渲染之前拦截HTML并替换文本?
如果可能的话,它会不会太慢以至于不值得?
或者,您是否建议我做一个策略,即我构建一个生成器,我保留在我的工作站上,它从主模板为我构建每个 HTML 文件夹,然后一旦我从安装应用程序确定用户的语言,我就部署那些已经用我的安装应用程序完成的?
通过大量实验,我发现了一种丑陋的模板制作方式。就像我说的,这是不可取的并且有一些副作用:
您会在第一次 window 加载时看到一个闪光灯。在第一次加载具有 WebKit 小部件的应用程序 window 时,您需要隐藏 window 直到第二次显示页面内容。我猜你必须为此使用 属性。
导航时,每个页面加载两次。几乎不引人注意,但还不够好发展。
我发现 Bootstrap CSS 有一个奇怪的问题,它使我的 table 网格行非常大并且没有正确应用 CSS出于某种奇怪的原因。我也许可以调整 CSS 来解决这个问题。
不幸的是,除了 didFinishLoadForFrame
,我发现没有其他事件可以拦截。但是,到那时,该页面已经下载并呈现了至少一次一微秒。最好在此之前拦截一些事件,我有完整的 HTML,并在显示之前在那里进行交换。我没有找到这样的事件。但是,如果有人发现这样的事件——那可能会使它成为一个很好的模板解决方案。
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
{
DOMHTMLElement * htmlNode =
(DOMHTMLElement *) [[[frame DOMDocument] getElementsByTagName: @"html"] item: 0];
NSString *s = [htmlNode outerHTML];
if ([s containsString:@"<!-- processed -->"]) {
return;
}
NSURL *oBaseURL = [[[frame dataSource] request] URL];
s = [s stringByReplacingOccurrencesOfString:@"%EXAMPLE%" withString:@"ZZZ"];
s = [s stringByReplacingOccurrencesOfString:@"</head>" withString:@"<!-- processed -->\n</head>"];
[frame loadHTMLString:s baseURL:oBaseURL];
}
以上将查看包含%EXAMPLE%
的HTML并将其替换为ZZZ
。
最后,我意识到这是低效的,因为页面闪烁,并且在需要大量替换的长文本上,可能会有一些非常明显的延迟。更好的方法是创建一个编译时生成器。这将创建一个 HTML 文件夹,其中包含 %PARAMETERIZED_TAGS%
而不是英文文本。然后,在你的 "Build Phase" 中创建一个 "Run Script" 来运行你用你想要的任何语言创建的一些 program/script 从所有可用的 lang-[=42= 生成每个 HTML 文件夹] 目录中的文件,其中 XX 是语言代码,如 'en'、'de' 等。它读取 HTML 文件,在 lang-XX.plist 文件,并用该语言的文本替换该文本。这样,编译后,每种语言都有几个 HTML 文件夹,已经在使用翻译后的字符串。这是有效的,因为它允许您有一个单独的 HTML 文件夹来处理您的代码,而不必执行以每种语言创建每个 HTML 文件夹的极其繁琐的过程,也不必保持混乱。编译时生成器会为你做那件事。但是——您必须构建该编译时生成器。