Search in sources :

Example 1 with MsgHtmlTagNode

use of com.google.template.soy.soytree.MsgHtmlTagNode in project closure-templates by google.

the class MsgFuncGenerator method collectVarNameListAndToPyExprMap.

/**
 * Private helper to process and collect all variables used within this msg node for code
 * generation.
 *
 * @return A Map populated with all the variables used with in this message node, using {@link
 *     MsgPlaceholderInitialNode#genBasePhName}.
 */
private Map<PyExpr, PyExpr> collectVarNameListAndToPyExprMap() {
    Map<PyExpr, PyExpr> nodePyVarToPyExprMap = new LinkedHashMap<>();
    for (Map.Entry<String, MsgSubstUnitNode> entry : msgNode.getVarNameToRepNodeMap().entrySet()) {
        MsgSubstUnitNode substUnitNode = entry.getValue();
        PyExpr substPyExpr = null;
        if (substUnitNode instanceof MsgPlaceholderNode) {
            SoyNode phInitialNode = ((AbstractParentSoyNode<?>) substUnitNode).getChild(0);
            if (phInitialNode instanceof PrintNode || phInitialNode instanceof CallNode || phInitialNode instanceof RawTextNode) {
                substPyExpr = PyExprUtils.concatPyExprs(genPyExprsVisitor.exec(phInitialNode)).toPyString();
            }
            // when the placeholder is generated by HTML tags
            if (phInitialNode instanceof MsgHtmlTagNode) {
                substPyExpr = PyExprUtils.concatPyExprs(genPyExprsVisitor.execOnChildren((ParentSoyNode<?>) phInitialNode)).toPyString();
            }
        } else if (substUnitNode instanceof MsgPluralNode) {
            // Translates {@link MsgPluralNode#pluralExpr} into a Python lookup expression.
            // Note that {@code pluralExpr} represents the soy expression of the {@code plural} attr,
            // i.e. the {@code $numDrafts} in {@code {plural $numDrafts}...{/plural}}.
            substPyExpr = translateToPyExprVisitor.exec(((MsgPluralNode) substUnitNode).getExpr());
        } else if (substUnitNode instanceof MsgSelectNode) {
            substPyExpr = translateToPyExprVisitor.exec(((MsgSelectNode) substUnitNode).getExpr());
        }
        if (substPyExpr != null) {
            nodePyVarToPyExprMap.put(new PyStringExpr("'" + entry.getKey() + "'"), substPyExpr);
        }
    }
    return nodePyVarToPyExprMap;
}
Also used : AbstractParentSoyNode(com.google.template.soy.soytree.AbstractParentSoyNode) SoyNode(com.google.template.soy.soytree.SoyNode) ParentSoyNode(com.google.template.soy.soytree.SoyNode.ParentSoyNode) AbstractParentSoyNode(com.google.template.soy.soytree.AbstractParentSoyNode) MsgSelectNode(com.google.template.soy.soytree.MsgSelectNode) PyStringExpr(com.google.template.soy.pysrc.restricted.PyStringExpr) MsgSubstUnitNode(com.google.template.soy.soytree.SoyNode.MsgSubstUnitNode) CallNode(com.google.template.soy.soytree.CallNode) LinkedHashMap(java.util.LinkedHashMap) PyExpr(com.google.template.soy.pysrc.restricted.PyExpr) ParentSoyNode(com.google.template.soy.soytree.SoyNode.ParentSoyNode) AbstractParentSoyNode(com.google.template.soy.soytree.AbstractParentSoyNode) MsgHtmlTagNode(com.google.template.soy.soytree.MsgHtmlTagNode) PrintNode(com.google.template.soy.soytree.PrintNode) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) RawTextNode(com.google.template.soy.soytree.RawTextNode) MsgPlaceholderNode(com.google.template.soy.soytree.MsgPlaceholderNode) MsgPluralNode(com.google.template.soy.soytree.MsgPluralNode)

Example 2 with MsgHtmlTagNode

use of com.google.template.soy.soytree.MsgHtmlTagNode in project closure-templates by google.

the class TemplateParserTest method testParseMsgStmt.

@Test
public void testParseMsgStmt() throws Exception {
    String templateBody = "{@param usedMb :?}{@param learnMoreUrl :?}\n" + "  {msg desc=\"Tells user's quota usage.\"}\n" + "    You're currently using {$usedMb} MB of your quota.{sp}\n" + "    <a href=\"{$learnMoreUrl}\">Learn more</A>\n" + "    <br /><br />\n" + "  {/msg}\n" + "  {msg meaning=\"noun\" desc=\"\" hidden=\"true\"}Archive{/msg}\n" + "  {msg meaning=\"noun\" desc=\"The archive (noun).\"}Archive{/msg}\n" + "  {msg meaning=\"verb\" desc=\"\"}Archive{/msg}\n" + "  {msg desc=\"\"}Archive{/msg}\n";
    List<StandaloneNode> nodes = parseTemplateContent(templateBody, FAIL).getChildren();
    assertEquals(5, nodes.size());
    MsgNode mn0 = ((MsgFallbackGroupNode) nodes.get(0)).getMsg();
    assertEquals("Tells user's quota usage.", mn0.getDesc());
    assertEquals(null, mn0.getMeaning());
    assertEquals(false, mn0.isHidden());
    assertEquals(8, mn0.numChildren());
    assertEquals("You're currently using ", ((RawTextNode) mn0.getChild(0)).getRawText());
    MsgPlaceholderNode mpn1 = (MsgPlaceholderNode) mn0.getChild(1);
    assertEquals("$usedMb", ((PrintNode) mpn1.getChild(0)).getExpr().toSourceString());
    assertEquals(" MB of your quota. ", ((RawTextNode) mn0.getChild(2)).getRawText());
    MsgPlaceholderNode mpn3 = (MsgPlaceholderNode) mn0.getChild(3);
    MsgHtmlTagNode mhtn3 = (MsgHtmlTagNode) mpn3.getChild(0);
    assertEquals("a", mhtn3.getLcTagName());
    assertEquals("START_LINK", mhtn3.genBasePhName());
    assertEquals("<a href=\"{$learnMoreUrl}\">", mhtn3.toSourceString());
    assertEquals(3, mhtn3.numChildren());
    assertEquals("<a href=\"", ((RawTextNode) mhtn3.getChild(0)).getRawText());
    assertEquals("$learnMoreUrl", ((PrintNode) mhtn3.getChild(1)).getExpr().toSourceString());
    assertEquals("\">", ((RawTextNode) mhtn3.getChild(2)).getRawText());
    assertEquals("Learn more", ((RawTextNode) mn0.getChild(4)).getRawText());
    MsgPlaceholderNode mpn5 = (MsgPlaceholderNode) mn0.getChild(5);
    MsgHtmlTagNode mhtn5 = (MsgHtmlTagNode) mpn5.getChild(0);
    assertEquals("/a", mhtn5.getLcTagName());
    assertEquals("END_LINK", mhtn5.genBasePhName());
    assertEquals("</A>", mhtn5.toSourceString());
    MsgPlaceholderNode mpn6 = (MsgPlaceholderNode) mn0.getChild(6);
    MsgHtmlTagNode mhtn6 = (MsgHtmlTagNode) mpn6.getChild(0);
    assertEquals("BREAK", mhtn6.genBasePhName());
    assertTrue(mpn6.shouldUseSameVarNameAs((MsgPlaceholderNode) mn0.getChild(7)));
    assertFalse(mpn6.shouldUseSameVarNameAs(mpn5));
    assertFalse(mpn5.shouldUseSameVarNameAs(mpn3));
    MsgFallbackGroupNode mfgn1 = (MsgFallbackGroupNode) nodes.get(1);
    assertEquals("{msg meaning=\"noun\" desc=\"\" hidden=\"true\"}Archive{/msg}", mfgn1.toSourceString());
    MsgNode mn1 = mfgn1.getMsg();
    assertEquals("", mn1.getDesc());
    assertEquals("noun", mn1.getMeaning());
    assertEquals(true, mn1.isHidden());
    assertEquals(1, mn1.numChildren());
    assertEquals("Archive", ((RawTextNode) mn1.getChild(0)).getRawText());
}
Also used : StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) MsgFallbackGroupNode(com.google.template.soy.soytree.MsgFallbackGroupNode) MsgHtmlTagNode(com.google.template.soy.soytree.MsgHtmlTagNode) PrintNode(com.google.template.soy.soytree.PrintNode) MsgNode(com.google.template.soy.soytree.MsgNode) MsgPlaceholderNode(com.google.template.soy.soytree.MsgPlaceholderNode) Test(org.junit.Test)

Example 3 with MsgHtmlTagNode

use of com.google.template.soy.soytree.MsgHtmlTagNode 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 4 with MsgHtmlTagNode

use of com.google.template.soy.soytree.MsgHtmlTagNode in project closure-templates by google.

the class InsertMsgsVisitor method buildReplacementNodesFromTranslation.

/**
 * Private helper for visitMsgFallbackGroupNode() to build the list of replacement nodes for a
 * message from its translation.
 */
private void buildReplacementNodesFromTranslation(MsgNode msg, SoyMsg translation) {
    currReplacementNodes = Lists.newArrayList();
    for (SoyMsgPart msgPart : translation.getParts()) {
        if (msgPart instanceof SoyMsgRawTextPart) {
            // Append a new RawTextNode to the currReplacementNodes list.
            String rawText = ((SoyMsgRawTextPart) msgPart).getRawText();
            currReplacementNodes.add(new RawTextNode(nodeIdGen.genId(), rawText, msg.getSourceLocation()));
        } else if (msgPart instanceof SoyMsgPlaceholderPart) {
            // Get the representative placeholder node and iterate through its contents.
            String placeholderName = ((SoyMsgPlaceholderPart) msgPart).getPlaceholderName();
            MsgPlaceholderNode placeholderNode = msg.getRepPlaceholderNode(placeholderName);
            for (StandaloneNode contentNode : placeholderNode.getChildren()) {
                // simply add the content node to the currReplacementNodes list being built.
                if (contentNode instanceof MsgHtmlTagNode) {
                    currReplacementNodes.addAll(((MsgHtmlTagNode) contentNode).getChildren());
                } else {
                    currReplacementNodes.add(contentNode);
                }
            }
        } else {
            throw new AssertionError();
        }
    }
}
Also used : StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) SoyMsgPlaceholderPart(com.google.template.soy.msgs.restricted.SoyMsgPlaceholderPart) MsgHtmlTagNode(com.google.template.soy.soytree.MsgHtmlTagNode) SoyMsgRawTextPart(com.google.template.soy.msgs.restricted.SoyMsgRawTextPart) RawTextNode(com.google.template.soy.soytree.RawTextNode) MsgPlaceholderNode(com.google.template.soy.soytree.MsgPlaceholderNode) SoyMsgPart(com.google.template.soy.msgs.restricted.SoyMsgPart)

Example 5 with MsgHtmlTagNode

use of com.google.template.soy.soytree.MsgHtmlTagNode in project closure-templates by google.

the class GenJsCodeVisitorAssistantForMsgs method genGoogMsgPlaceholder.

/**
 * Returns a code chunk for the given placeholder node.
 */
protected CodeChunk.WithValue genGoogMsgPlaceholder(MsgPlaceholderNode msgPhNode) {
    List<CodeChunk.WithValue> contentChunks = new ArrayList<>();
    for (StandaloneNode contentNode : msgPhNode.getChildren()) {
        if (contentNode instanceof MsgHtmlTagNode && !isComputableAsJsExprsVisitor.exec(contentNode)) {
            // This is a MsgHtmlTagNode that is not computable as JS expressions. Visit it to
            // generate code to define the 'htmlTag<n>' variable.
            visit(contentNode);
            contentChunks.add(id("htmlTag" + contentNode.getId()));
        } else if (contentNode instanceof CallNode) {
            // If the CallNode has any CallParamContentNode children that are not computable as JS
            // expressions, visit them to generate code to define their respective 'param<n>' variables.
            CallNode callNode = (CallNode) contentNode;
            for (CallParamNode grandchild : callNode.getChildren()) {
                if (grandchild instanceof CallParamContentNode && !isComputableAsJsExprsVisitor.exec(grandchild)) {
                    visit(grandchild);
                }
            }
            CodeChunk.WithValue call = genCallCodeUtils.gen(callNode, templateAliases, translationContext, errorReporter);
            contentChunks.add(call);
        } else {
            List<CodeChunk.WithValue> chunks = genJsExprsVisitor.exec(contentNode);
            contentChunks.add(CodeChunkUtils.concatChunks(chunks));
        }
    }
    return CodeChunkUtils.concatChunks(contentChunks);
}
Also used : StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) CallParamContentNode(com.google.template.soy.soytree.CallParamContentNode) CodeChunk(com.google.template.soy.jssrc.dsl.CodeChunk) CallParamNode(com.google.template.soy.soytree.CallParamNode) ArrayList(java.util.ArrayList) MsgHtmlTagNode(com.google.template.soy.soytree.MsgHtmlTagNode) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) CallNode(com.google.template.soy.soytree.CallNode)

Aggregations

MsgHtmlTagNode (com.google.template.soy.soytree.MsgHtmlTagNode)8 MsgPlaceholderNode (com.google.template.soy.soytree.MsgPlaceholderNode)5 RawTextNode (com.google.template.soy.soytree.RawTextNode)5 StandaloneNode (com.google.template.soy.soytree.SoyNode.StandaloneNode)5 MsgFallbackGroupNode (com.google.template.soy.soytree.MsgFallbackGroupNode)4 MsgNode (com.google.template.soy.soytree.MsgNode)4 Test (org.junit.Test)4 CallNode (com.google.template.soy.soytree.CallNode)3 PrintNode (com.google.template.soy.soytree.PrintNode)3 SoyMsgPlaceholderPart (com.google.template.soy.msgs.restricted.SoyMsgPlaceholderPart)2 SoyFileSetNode (com.google.template.soy.soytree.SoyFileSetNode)2 TemplateNode (com.google.template.soy.soytree.TemplateNode)2 ImmutableList (com.google.common.collect.ImmutableList)1 Statement (com.google.template.soy.jbcsrc.restricted.Statement)1 CodeChunk (com.google.template.soy.jssrc.dsl.CodeChunk)1 SoyMsgBundle (com.google.template.soy.msgs.SoyMsgBundle)1 SoyMsg (com.google.template.soy.msgs.restricted.SoyMsg)1 SoyMsgBundleImpl (com.google.template.soy.msgs.restricted.SoyMsgBundleImpl)1 SoyMsgPart (com.google.template.soy.msgs.restricted.SoyMsgPart)1 SoyMsgRawTextPart (com.google.template.soy.msgs.restricted.SoyMsgRawTextPart)1