Code Monkey home page Code Monkey logo

amp-renderer's Introduction

AMP Renderer

Python 3.6+ Build Status Coverage

Unofficial Python port of server-side rendering from AMP Optimizer. Tested in Python 3.8 and above, but works on Python 3.6+.

AMP Renderer performs the following optimizations:

  1. Inject the specific layout markup into each AMP element
  2. Insert the AMP runtime styles into the document
  3. Remove the AMP boilerplate styles, if possible
  4. Mark the document as “transformed” with the appropriate tags on the html element
  5. Insert img tags for images with the data-hero attribute

It also makes these formatting updates:

  1. Remove empty class and style tags for AMP HTML elements
  2. Convert tag names and attribute names to lowercase
  3. Convert numerical attribute values to strings
  4. Use double quotes ("") for attributes, and escape double quotes inside attribute values
  5. Remove whitespace between html attributes
  6. If desired, removes comments (disabled by default)
  7. If desired, trims whitespace around HTML attribute values (disabled by default, and not always a good idea)

AMPRenderer can be used on a block of arbitrary HTML, but when used on a full document, it will insert the AMP runtime styles and, if possible, remove the AMP boilerplate styles.

Boilerplate styles can be removed except in these cases:

  • An AMP element uses an unsupported value for the layout attribute
  • amp-audio is used
  • There is at least one amp-experiment active
  • Transformation fails for one or more elements due to an invalid attribute value for media, sizes, or heights
  • Any render-delaying extension is used. Currently this means:
    • amp-dynamic-css-classes
    • amp-story

If boilerplate styles can’t be removed, the attribute no_boilerplate will be set to True after calling render; otherwise it will be False. Until render runs, the no_boilerplate attribute isn’t set at all.

Usage

If using Django, you can use the Django AMP Renderer middleware.

Otherwise, install via PyPI:

pip install amp-renderer

Minimal usage:

from amp_renderer import AMPRenderer

...

RUNTIME_VERSION = "012345678" /* Current AMP runtime version number */
RUNTIME_STYLES = "..." /* Current contents of https://cdn.ampproject.org/v0.css */

renderer = AMPRenderer(
	runtime_version=RUNTIME_VERSION,
	runtime_styles=RUNTIME_STYLES)

original_html = """
    <!doctype html>
    <html ⚡>
      ...
    </html>
"""

result = renderer.render(original_html)

print(result)

Remove comments and/or trim attributes:

renderer.strip_comments = True
renderer.trim_attributes = True
result = renderer.render(original_html)

print(result)

The AMPRenderer class inherits from HTMLParser, and can be similarly extended.

Testing, etc.

Install development requirements (Requires Python >= 3.8):

make install

Sort imports:

make format

Lint:

make lint

Test:

make test

Discussion

There are still some aspects of the official AMP Optimizer implementation that haven’t been addressed yet. PRs welcome.

General

  • Tested against AMP Optimizer’s ServerSideRendering spec
  • Automatic runtime version management

Dynamic attributes

  • Support sizes, media, and heights via CSS injection
  • Group CSS injections for media attributes by shared media queries to reduce necessary bytes
  • Support percent values in heights
  • Warn or fail if CSS injection puts the amp-custom element over the byte limit

Hero Images

  • Inject img tag for amp-imgs with the data-hero attribute
  • Enforce 2-image limit on data-hero
  • Autodetect hero images
  • Support hero image functionality for amp-iframe, amp-video, and amp-video-iframe

Performance

The Python AMP Renderer does not insert preload links into the head of the DOM object for hero images; This can be done by hand for more control over the critical path.

amp-renderer's People

Contributors

chasefinch avatar dependabot[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

amp-renderer's Issues

Enable & pass additional 2 spec tests

Currently, media queries are not grouped by their media condition, and this causes two tests to fail:

  • converts_heights_attribute_to_css
  • converts_media_attribute_to_css

When implementing media grouping, re-add these tests.

Cannot add custom RUNTIME_STYLES when using amp-img

I want to add my custom RUNTIME_STYLES CSS to my HTML page when using amp-img.
My backend is Flask so this is my code in the backend.

@app.route("/testRenderer")
def testRenderer_page():
    renderer = AMPRenderer(
        runtime_version="002106182132000",
        runtime_styles=""".testRenderer{background-color:red;}body{background-color:pink;}""",
    )
    renderer.should_strip_comments = True
    renderer.should_trim_attributes = True

    return renderer.render(render_template("testRenderer.html"))

if my testRenderer.html like this one

<!doctype html>
<html ⚡️>

<head>
</head>

<body>
    <div class="testRenderer">testRenderer</div>
    <amp-img src="https://i.ibb.co/N7br0BR/ezgif-com-resize-40.jpg" width="500px" height="500px" layout="fixed">
    </amp-img>
</body>

</html>

This is the result
image

if my testRenderer.html like this one

<!doctype html>
<html ⚡️>

<head>
    <script async src=https://cdn.ampproject.org/v0.js></script>
</head>

<body>
    <div id="testDiv" class="testClass"></div>
    <div class="testRenderer">testRenderer</div>
    <amp-img src="https://i.ibb.co/N7br0BR/ezgif-com-resize-40.jpg" width="500px" height="500px" layout="fixed">
    </amp-img>
</body>

</html>

The result is
image

I want to show the img and also have the pink background (also a red background in div) - I mean my CSS style.

I just found the problem is all about <script async src=https://cdn.ampproject.org/v0.js></script>. When it appears in the head tag, content of <style amp-runtime="">...</style> use css of https://cdn.ampproject.org/v0.js and do not use my css, and vice versa.
image

Thank you for your help

Apply `sizes` to the underlying img element of `amp-img`

There are two related problems with the current implementation:

  • A sizes attribute on an amp-img with data-hero specified is applied to the injected img tag*, but then overwritten by the runtime. This is generally OK, as the browser always has a suitable sizes definition to select from, even if it isn’t the one the user wrote.
  • A sizes attribute on an amp-img without data-hero applies the amp-specific styles, but since the attribute is then removed from the amp-img, the correct sizes attribute is never added to the img by the runtime. This also usually works out okay because the runtime generates a new sizes attribute when creating the img, but it's still not correct/ideal.

*This is true here in amp-renderer, but not yet in AMP Optimizer; see 910

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.