Skip to main content

Python Hypertext Markup Language - Extension of HTML

Project description

version License tired-fox - phml stars - phml forks - phml

Python Hypertext Markup Language (phml)

GitHub release issues - phml quality testing test coverage

TOC

view - Documentation

Overview

The idea behind the creation of Python in Hypertext Markup Language (phml), is to allow for web page generation with direct access to python. This language pulls directly from frameworks like VueJS. There is conditional rendering, components, python elements, inline/embedded python blocks, and much more. Now let's dive into more about this language.

Let's start with the new python element. Python is a whitespace language. As such phml has the challenge of maintaining the indentation in an appropriate way. With phml, I have made the decision to allow you to have as much leading whitespace as you want as long as the indentation is consistent. This means that indentation is based on the first lines offset. Take this phml example:

<python>
    if True:
        print("Hello World")
</python>

This phml python block will adjust the offset so that the python is executed as seen below:

if True:
    print("Hello World")

So now we can write python code, now what? You can define functions and variables how you normally would and they are now available to the scope of the entire file. Take, for instance, the example from above, the one with py-src="urls('youtube')". You can define the URL function in the python element and it can be accessed in an element. So the code would look like this:

<python>
def URL(link: str) -> str:
    links = {
        "youtube": "https://youtube.com"
    }
    if link in links:
        return links[link]
    else:
        return ""
</python>

...

<a href="{URL('youtube')}">Youtube</a>

phml combines all python elements and treats them as a python file. All local variables and imports are parsed and stored so that they may be accessed later. With that in mind that means you have the full power of the python programming language.

Next up is inline python blocks. These are represented with {}. Any text in-between the brackets will be processed as python. This is mostly useful when you want to inject a value from python. Assume that there is a variable defined in the python element called message and it contains Hello World!. Now this variable can be used like this, <p>{ message }</p>, which renders to, <p>Hello World!</p>.

Note: Inline python blocks are only rendered in a Text element or inside an html attribute.

Multiline blocks are a lot like inline python blocks, but they also have some differences. You can do whatever you like inside this block, however if you expect a value to come from the block you must have at least one local variable. The last local variable defined in this block is used at the result/value.

Conditional Rendering with py-if, py-elif, and py-else is an extremely helpful tool in phml. py-if can be used alone and that the python inside it's value must be truthy for the element to be rendered. py-elif requires an element with a py-if or py-elif attribute immediately before it, and it's condition is rendered the same as py-if but only rendered if a py-if or py-elif first fails. py-else requires there to be either a py-if or a py-else immediately before it. It only renders if the previous element's condition fails. If py-elif or py-else is on an element, but the previous element isn't a py-if or py-elif then an exception will occur. Most importantly, the first element in a chain of conditions must be a py-if. For ease of use, instead of writing py-if, py-elif, or py-else can be written as @if, @elif, or @else respectively.

Other than conditions, there is also a built in py-for attribute. Any element with py-for will take a python for-loop expression that will be applied to that element. So if you did something like this:

<ul>
    <li py-for='i in range(3)'>
        <p>{i}</p>
    </li>
</ul>

The compiled html will be:

<ul>
    <li>
        <p>1</p>
    </li>
    <li>
        <p>2</p>
    </li>
    <li>
        <p>3</p>
    </li>
</ul>

The for and : in the for loops condition are optional. So you can combine for, i in range(10), and : or leave out for and : at your discretion. py-for can also be written as @for.

Python attributes are shortcuts for using inline python blocks in html attributes. Normally, in phml, you would inject python logic into an attribute similar to this: src="{url('youtube')}". If you would like to make the whole attribute value a python expression you may prefix any attribute with a py- or :. This keeps the attribute name the same after the prefix, but tells the parser that the entire value should be processed as python. So the previous example can also be expressed as py-src="URL('youtube')" or :src="URL('youtube')".

This language also has the ability to convert back to html and json with converting to html having more features. Converting to json is just a json representation of a phml ast. However, converting to html is where the magic happens. The compiler executes python blocks, substitutes components, and processes conditions to create a final html string that is dynamic to its original ast. A user may pass additional kwargs to the compiler to expose additional data to the execution of python blocks. If you wish to compile to a non supported language the compiler can take a callable that returns the final string. It passes all the data; components, kwargs, ast, etc… So if a user wishes to extend the language thay may.

:warning: This language is in early planning and development stages. All forms of feedback are encouraged.

How to use

PHML is in early planning so the use is limited.

The current version is able to parse phml using an html parser. This creates a phml ast which then can be converted back to phml for to json. Converting to html is coming soon, but will take type since that is the core functionality of this language. It will need to parse, execute, and handle imbedded python code.

Use

PHML provides file type variables for better ease of use. The types include HTML, PHML, and JSON. They can be imported with from phml import HTML, PHML, JSON.

First import the PHMLCore, from phml import PHMLCore. Then you can do the following:

core = PHMLCore().load("path/to/file.phml")
print(core.render())

By default PHMLCore.render() will return the html string. If you want to get a json string you may pass the file type variable JSON. PHMLCore.render(file_type=JSON).

If you want to write to a file you can call core.write("path/to/output/file.phml"). Same with render it defaults to html. You can change this the same way as render. core.write("path/to/otuput/file.json", file_type=JSON).

For both render and write you will first need to call core.load("path/to/source/file.phml"). This parses the source file and stores the ast in the parser. render and write then use that ast to create the desired output. Optionally if you already have a phml or html string or a properly formatted dict you can call core.parse(data) which will parse that information similar to load.

core.render and core.write return self which allows for method chaining. See the examples in example/ to see how this can be used.

Every time core.parse or core.load is called it will overwrite the stored ast variable.

For more information check out the API Docs

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

phml-0.1.1.tar.gz (1.1 MB view details)

Uploaded Source

Built Distribution

phml-0.1.1-py3-none-any.whl (61.7 kB view details)

Uploaded Python 3

File details

Details for the file phml-0.1.1.tar.gz.

File metadata

  • Download URL: phml-0.1.1.tar.gz
  • Upload date:
  • Size: 1.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.5

File hashes

Hashes for phml-0.1.1.tar.gz
Algorithm Hash digest
SHA256 3df671d7a1d6c568504584107ed8bf87fcd026c2ce6edb3c7a1c512bc7bb6ea4
MD5 e8ff97c55114a241326cd4c314d6bfa6
BLAKE2b-256 de62e6bd57a3adc26a1cf91d9a82652ebedd1e1f389f3f9fee0badde48b84b9f

See more details on using hashes here.

File details

Details for the file phml-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: phml-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 61.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.5

File hashes

Hashes for phml-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0d37ec4ffbf5b5c37df0396795674aaedce4257caff93651708d819c608cd7ae
MD5 85b7ccfcca91fd60fc44339ed63fb921
BLAKE2b-256 e823d81c1af99405838c31971c0801cf346b10d8cd1d920d54a2744c696a9999

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page