How can I perform string manipulations inside an amp-list template?

Viewed 1121

I can use amp-bind to update [href] for an anchor. If I include this same anchor in an amp-list template, though, [href] appears to mangled when the template is applied (it is prepended by the origin location and URI encoded). Notably, single quotes are missing around strings, resulting in an expression compile error.

In the following example, the link before amp-list updates fine on the button press, whereas the link produced by the amp-list template becomes mangled. Interestingly, the anchor in the template still reads fine; it's only after the template is applied that [href] gets mangled.

Anchor inside template:

<a href="https://amp-test/" [href]="path ? 'https://amp-test/' + path.split(' ').join('-') : 'https://amp-test/'">{{linkName}}</a>

Anchor after template is applied:

<a href="https://amp-test/" [href]="https://amp-test/path%20?%20%27https://amp-test/%27%20+%20path.split(%27%20%27).join(%27-%27)%20:%20%27https://amp-test/%27" target="_top" class="i-amphtml-error">one path</a>

So, some questions that might accompany the title question include: Are amp-bind operations supposed to work inside amp-list? i.e is what I'm seeing the expected behavior or a bug?

Minimal Example (jsfiddle)

results.json

{
    "items": [
        { "linkName": "one path" },
        { "linkName": "two path" }
    ]
}

index.html

<!doctype html>
<html ⚡>
<head>
    <title>amp-bind in amp-list</title>
    <meta charset="utf-8">
    <script async src="https://cdn.ampproject.org/v0.js"></script>
    <script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
    <script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
    <script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.1.js"></script>
    <link rel="canonical" href="https://cmphys.com/">
    <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
    <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>

    <style amp-custom>
    </style>
</head>
<body>
    <button on="tap:AMP.setState({path: 'relative path'})">Update</button>

    <hr>
    <p>
        <a href="https://amp-test/" [href]="path ? 'https://amp-test/' + path.split(' ').join('-') : 'https://amp-test/'">link</a>
    </p>

    <hr>
    <amp-list id="myList" class="list" layout="fixed" width="200" height="100" src="/results.json">
        <template type="amp-mustache">
            <a href="https://amp-test/" [href]="path ? 'https://amp-test/' + path.split(' ').join('-') : 'https://amp-test/'">{{linkName}}</a><br>
        </template>
    </amp-list>

</body>
</html>
1 Answers

Try using Sanitizers to manipulate your post's AMP content. For this, you should avoid banned URL protocols or expressions that would fail the AMP Validator.

Regarding amp-bind operations inside amp-list, you may want to check this documentation wherein it's mentioned that binding to <amp-list> components and attributes is allowed and it's behavior is that:

If expression is a string, fetches and renders JSON from the string URL. If expression is an object or array, renders the expression data.

Related