Search in sources :

Example 1 with SoyMsg

use of com.google.template.soy.msgs.restricted.SoyMsg in project closure-templates by google.

the class InsertMsgsVisitor method replaceMsgNode.

private void replaceMsgNode(MsgFallbackGroupNode node) {
    // Check for plural or select message. Either report error or don't replace.
    for (MsgNode msg : node.getChildren()) {
        if (msg.isPlrselMsg()) {
            errorReporter.report(node.getSourceLocation(), ENCOUNTERED_PLURAL_OR_SELECT);
            return;
        }
    }
    // Figure out which message we're going to use, and build its list of replacement nodes.
    currReplacementNodes = null;
    if (msgBundle != null) {
        for (MsgNode msg : node.getChildren()) {
            SoyMsg translation = msgBundle.getMsg(MsgUtils.computeMsgIdForDualFormat(msg));
            if (translation != null) {
                buildReplacementNodesFromTranslation(msg, translation);
                break;
            }
        }
    }
    if (currReplacementNodes == null) {
        buildReplacementNodesFromSource(node.getChild(0));
    }
    // Replace this MsgFallbackGroupNode with the replacement nodes.
    ParentSoyNode<StandaloneNode> parent = node.getParent();
    int indexInParent = parent.getChildIndex(node);
    parent.removeChild(indexInParent);
    parent.addChildren(indexInParent, currReplacementNodes);
    currReplacementNodes = null;
}
Also used : StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) SoyMsg(com.google.template.soy.msgs.restricted.SoyMsg) MsgNode(com.google.template.soy.soytree.MsgNode)

Example 2 with SoyMsg

use of com.google.template.soy.msgs.restricted.SoyMsg in project closure-templates by google.

the class ExtractMsgsVisitor method visitMsgNode.

@Override
protected void visitMsgNode(MsgNode node) {
    MsgPartsAndIds msgPartsAndIds = MsgUtils.buildMsgPartsAndComputeMsgIdForDualFormat(node);
    SoyMsg.Builder builder = SoyMsg.builder().setId(msgPartsAndIds.id);
    if (node.getMeaning() != null) {
        builder.setMeaning(node.getMeaning());
    }
    SoyMsg msg = builder.setDesc(node.getDesc()).setIsHidden(node.isHidden()).setContentType(node.getContentType()).setSourceLocation(node.getSourceLocation()).setIsPlrselMsg(node.isPlrselMsg()).setParts(msgPartsAndIds.parts).build();
    msgs.add(msg);
}
Also used : SoyMsg(com.google.template.soy.msgs.restricted.SoyMsg) MsgPartsAndIds(com.google.template.soy.msgs.internal.MsgUtils.MsgPartsAndIds)

Example 3 with SoyMsg

use of com.google.template.soy.msgs.restricted.SoyMsg in project closure-templates by google.

the class InsertMsgsVisitorTest method testFallbackMsgsUsingMsgBundle.

@Test
public void testFallbackMsgsUsingMsgBundle() {
    SoyFileSetNode soyTree = SoyFileSetParserBuilder.forFileContents(FALLBACK_TEST_FILE_CONTENT).parse().fileSet();
    TemplateNode template = (TemplateNode) SharedTestUtils.getNode(soyTree);
    // Before.
    assertThat(template.numChildren()).isEqualTo(4);
    assertThat(((MsgFallbackGroupNode) template.getChild(0)).numChildren()).isEqualTo(2);
    assertThat(((MsgFallbackGroupNode) template.getChild(1)).numChildren()).isEqualTo(2);
    assertThat(((MsgFallbackGroupNode) template.getChild(2)).numChildren()).isEqualTo(2);
    assertThat(((MsgFallbackGroupNode) template.getChild(3)).numChildren()).isEqualTo(2);
    // Build the translated message bundle.
    List<SoyMsg> translatedMsgs = Lists.newArrayList();
    MsgNode trans1FirstInstance = ((MsgFallbackGroupNode) template.getChild(1)).getChild(0);
    translatedMsgs.add(SoyMsg.builder().setId(MsgUtils.computeMsgIdForDualFormat(trans1FirstInstance)).setLocaleString("x-zz").setParts(ImmutableList.<SoyMsgPart>of(SoyMsgRawTextPart.of("ztrans1"))).build());
    MsgNode trans2FirstInstance = ((MsgFallbackGroupNode) template.getChild(2)).getChild(1);
    translatedMsgs.add(SoyMsg.builder().setId(MsgUtils.computeMsgIdForDualFormat(trans2FirstInstance)).setLocaleString("x-zz").setParts(ImmutableList.<SoyMsgPart>of(SoyMsgRawTextPart.of("ztrans2"))).build());
    SoyMsgBundle msgBundle = new SoyMsgBundleImpl("x-zz", translatedMsgs);
    // Execute the visitor.
    new InsertMsgsVisitor(msgBundle, FAIL).insertMsgs(template);
    // After.
    assertThat(template.numChildren()).isEqualTo(4);
    assertThat(((RawTextNode) template.getChild(0)).getRawText()).isEqualTo("noTrans1");
    assertThat(((RawTextNode) template.getChild(1)).getRawText()).isEqualTo("ztrans1");
    assertThat(((RawTextNode) template.getChild(2)).getRawText()).isEqualTo("ztrans2");
    assertThat(((RawTextNode) template.getChild(3)).getRawText()).isEqualTo("ztrans1");
}
Also used : TemplateNode(com.google.template.soy.soytree.TemplateNode) SoyMsg(com.google.template.soy.msgs.restricted.SoyMsg) SoyMsgBundleImpl(com.google.template.soy.msgs.restricted.SoyMsgBundleImpl) MsgFallbackGroupNode(com.google.template.soy.soytree.MsgFallbackGroupNode) SoyFileSetNode(com.google.template.soy.soytree.SoyFileSetNode) SoyMsgBundle(com.google.template.soy.msgs.SoyMsgBundle) RawTextNode(com.google.template.soy.soytree.RawTextNode) MsgNode(com.google.template.soy.soytree.MsgNode) Test(org.junit.Test)

Example 4 with SoyMsg

use of com.google.template.soy.msgs.restricted.SoyMsg in project closure-templates by google.

the class InsertMsgsVisitorTest method testBasicMsgsUsingMsgBundle.

@Test
public void testBasicMsgsUsingMsgBundle() {
    SoyFileSetNode soyTree = SoyFileSetParserBuilder.forFileContents(BASIC_TEST_FILE_CONTENT).parse().fileSet();
    TemplateNode template = (TemplateNode) SharedTestUtils.getNode(soyTree);
    // Before.
    assertThat(template.numChildren()).isEqualTo(5);
    MsgNode msg = ((MsgFallbackGroupNode) template.getChild(2)).getChild(0);
    assertThat(msg.numChildren()).isEqualTo(5);
    MsgHtmlTagNode msgHtmlTag2 = (MsgHtmlTagNode) ((MsgPlaceholderNode) msg.getChild(2)).getChild(0);
    assertThat(msgHtmlTag2.numChildren()).isEqualTo(3);
    MsgHtmlTagNode msgHtmlTag4 = (MsgHtmlTagNode) ((MsgPlaceholderNode) msg.getChild(4)).getChild(0);
    assertThat(msgHtmlTag4.numChildren()).isEqualTo(1);
    assertThat(((RawTextNode) msgHtmlTag4.getChild(0)).getRawText()).isEqualTo("</a>");
    // Build the translated message bundle.
    List<SoyMsg> translatedMsgs = Lists.newArrayList();
    // Original (en): random{{FOO}}{{START_LINK}}slimy{{END_LINK}}
    // Translation (x-zz): {{START_LINK}}zslimy{{END_LINK}}{{FOO}}zrandom
    translatedMsgs.add(SoyMsg.builder().setId(MsgUtils.computeMsgIdForDualFormat(msg)).setLocaleString("x-zz").setParts(ImmutableList.of(new SoyMsgPlaceholderPart("START_LINK", /* placeholderExample= */
    null), SoyMsgRawTextPart.of("zslimy"), new SoyMsgPlaceholderPart("END_LINK", /* placeholderExample= */
    null), new SoyMsgPlaceholderPart("FOO", /* placeholderExample= */
    null), SoyMsgRawTextPart.of("zrandom"))).build());
    // Note: This bundle has no translation for the message "dairy{$moo}".
    SoyMsgBundle msgBundle = new SoyMsgBundleImpl("x-zz", translatedMsgs);
    // Execute the visitor.
    new InsertMsgsVisitor(msgBundle, FAIL).insertMsgs(template);
    // After.
    assertThat(template.numChildren()).isEqualTo(12);
    assertThat(((PrintNode) template.getChild(0)).getExpr().toSourceString()).isEqualTo("$boo");
    assertThat(((RawTextNode) template.getChild(1)).getRawText()).isEqualTo("scary ");
    assertThat(((RawTextNode) template.getChild(2)).getRawText()).isEqualTo("<a href=\"");
    assertThat(((PrintNode) template.getChild(3)).getExpr().toSourceString()).isEqualTo("$goo");
    assertThat(((RawTextNode) template.getChild(4)).getRawText()).isEqualTo("\">");
    assertThat(((RawTextNode) template.getChild(5)).getRawText()).isEqualTo("zslimy");
    assertThat(((RawTextNode) template.getChild(6)).getRawText()).isEqualTo("</a>");
    assertThat(((PrintNode) template.getChild(7)).getExpr().toSourceString()).isEqualTo("$foo");
    assertThat(((RawTextNode) template.getChild(8)).getRawText()).isEqualTo("zrandom");
    assertThat(((RawTextNode) template.getChild(9)).getRawText()).isEqualTo(" ");
    assertThat(((RawTextNode) template.getChild(10)).getRawText()).isEqualTo("dairy");
    assertThat(((PrintNode) template.getChild(11)).getExpr().toSourceString()).isEqualTo("$moo");
}
Also used : TemplateNode(com.google.template.soy.soytree.TemplateNode) SoyMsg(com.google.template.soy.msgs.restricted.SoyMsg) SoyMsgPlaceholderPart(com.google.template.soy.msgs.restricted.SoyMsgPlaceholderPart) SoyMsgBundleImpl(com.google.template.soy.msgs.restricted.SoyMsgBundleImpl) MsgFallbackGroupNode(com.google.template.soy.soytree.MsgFallbackGroupNode) SoyFileSetNode(com.google.template.soy.soytree.SoyFileSetNode) MsgHtmlTagNode(com.google.template.soy.soytree.MsgHtmlTagNode) RawTextNode(com.google.template.soy.soytree.RawTextNode) SoyMsgBundle(com.google.template.soy.msgs.SoyMsgBundle) MsgNode(com.google.template.soy.soytree.MsgNode) Test(org.junit.Test)

Example 5 with SoyMsg

use of com.google.template.soy.msgs.restricted.SoyMsg in project closure-templates by google.

the class XliffGenerator method generateXliff.

/**
 * Generates the output XLIFF file content for a given SoyMsgBundle.
 *
 * @param msgBundle The SoyMsgBundle to process.
 * @param sourceLocaleString The source language/locale string of the messages.
 * @param targetLocaleString The target language/locale string of the messages (optional). If
 *     specified, the resulting XLIFF file will specify this target language and will contain
 *     empty 'target' tags. If not specified, the resulting XLIFF file will not contain target
 *     language and will not contain 'target' tags.
 * @return The generated XLIFF file content.
 */
static CharSequence generateXliff(SoyMsgBundle msgBundle, String sourceLocaleString, @Nullable String targetLocaleString) {
    Escaper attributeEscaper = XmlEscapers.xmlAttributeEscaper();
    Escaper contentEscaper = XmlEscapers.xmlContentEscaper();
    boolean hasTarget = targetLocaleString != null && targetLocaleString.length() > 0;
    IndentedLinesBuilder ilb = new IndentedLinesBuilder(2);
    ilb.appendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    ilb.appendLine("<xliff version=\"1.2\" xmlns=\"urn:oasis:names:tc:xliff:document:1.2\">");
    ilb.increaseIndent();
    ilb.appendLineStart("<file original=\"SoyMsgBundle\" datatype=\"x-soy-msg-bundle\"", " xml:space=\"preserve\"", " source-language=\"", attributeEscaper.escape(sourceLocaleString), "\"");
    if (hasTarget) {
        ilb.appendParts(" target-language=\"", attributeEscaper.escape(targetLocaleString), "\"");
    }
    ilb.appendLineEnd(">");
    ilb.increaseIndent();
    ilb.appendLine("<body>");
    ilb.increaseIndent();
    for (SoyMsg msg : msgBundle) {
        // Begin 'trans-unit'.
        ilb.appendLineStart("<trans-unit id=\"", Long.toString(msg.getId()), "\"");
        String contentType = msg.getContentType();
        if (contentType != null && contentType.length() > 0) {
            String xliffDatatype = CONTENT_TYPE_TO_XLIFF_DATATYPE_MAP.get(contentType);
            if (xliffDatatype == null) {
                // just use the contentType string
                xliffDatatype = contentType;
            }
            ilb.appendParts(" datatype=\"", attributeEscaper.escape(xliffDatatype), "\"");
        }
        ilb.appendLineEnd(">");
        ilb.increaseIndent();
        // Source.
        ilb.appendLineStart("<source>");
        for (SoyMsgPart msgPart : msg.getParts()) {
            if (msgPart instanceof SoyMsgRawTextPart) {
                String rawText = ((SoyMsgRawTextPart) msgPart).getRawText();
                ilb.append(contentEscaper.escape(rawText));
            } else if (msgPart instanceof SoyMsgPlaceholderPart) {
                SoyMsgPlaceholderPart placeholder = (SoyMsgPlaceholderPart) msgPart;
                ilb.appendParts("<x id=\"", attributeEscaper.escape(placeholder.getPlaceholderName()), "\"" + // convention so we add it in the hope that tools will support it anyway.
                (placeholder.getPlaceholderExample() != null ? " example=\"" + attributeEscaper.escape(placeholder.getPlaceholderExample()) + "\"" : "") + "/>");
            } else {
                throw new RuntimeException("Xliff doesn't support plurals or genders. " + msg.getSourceLocations());
            }
        }
        ilb.appendLineEnd("</source>");
        // Target.
        if (hasTarget) {
            ilb.appendLine("<target/>");
        }
        // Description and meaning.
        String desc = msg.getDesc();
        if (desc != null && desc.length() > 0) {
            ilb.appendLine("<note priority=\"1\" from=\"description\">", contentEscaper.escape(desc), "</note>");
        }
        String meaning = msg.getMeaning();
        if (meaning != null && meaning.length() > 0) {
            ilb.appendLine("<note priority=\"1\" from=\"meaning\">", contentEscaper.escape(meaning), "</note>");
        }
        // End 'trans-unit'.
        ilb.decreaseIndent();
        ilb.appendLine("</trans-unit>");
    }
    ilb.decreaseIndent();
    ilb.appendLine("</body>");
    ilb.decreaseIndent();
    ilb.appendLine("</file>");
    ilb.decreaseIndent();
    ilb.appendLine("</xliff>");
    return ilb;
}
Also used : SoyMsg(com.google.template.soy.msgs.restricted.SoyMsg) SoyMsgPlaceholderPart(com.google.template.soy.msgs.restricted.SoyMsgPlaceholderPart) IndentedLinesBuilder(com.google.template.soy.base.internal.IndentedLinesBuilder) SoyMsgRawTextPart(com.google.template.soy.msgs.restricted.SoyMsgRawTextPart) Escaper(com.google.common.escape.Escaper) SoyMsgPart(com.google.template.soy.msgs.restricted.SoyMsgPart)

Aggregations

SoyMsg (com.google.template.soy.msgs.restricted.SoyMsg)8 SoyMsgBundle (com.google.template.soy.msgs.SoyMsgBundle)5 SoyMsgBundleImpl (com.google.template.soy.msgs.restricted.SoyMsgBundleImpl)4 MsgNode (com.google.template.soy.soytree.MsgNode)4 Test (org.junit.Test)4 SoyMsgPart (com.google.template.soy.msgs.restricted.SoyMsgPart)3 MsgFallbackGroupNode (com.google.template.soy.soytree.MsgFallbackGroupNode)3 SoyFileSetNode (com.google.template.soy.soytree.SoyFileSetNode)3 TemplateNode (com.google.template.soy.soytree.TemplateNode)3 SoyMsgPlaceholderPart (com.google.template.soy.msgs.restricted.SoyMsgPlaceholderPart)2 RawTextNode (com.google.template.soy.soytree.RawTextNode)2 SoyFileNode (com.google.template.soy.soytree.SoyFileNode)2 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Escaper (com.google.common.escape.Escaper)1 ParseResult (com.google.template.soy.SoyFileSetParser.ParseResult)1 IndentedLinesBuilder (com.google.template.soy.base.internal.IndentedLinesBuilder)1 ExtractMsgsVisitor (com.google.template.soy.msgs.internal.ExtractMsgsVisitor)1 MsgPartsAndIds (com.google.template.soy.msgs.internal.MsgUtils.MsgPartsAndIds)1 SoyMsgRawTextPart (com.google.template.soy.msgs.restricted.SoyMsgRawTextPart)1