Part 0 - Htmlista Mode¶
The basics¶
Let’s start by using the CLI to create a new application:
anpylar-application --htmlista --tutorial top0
Note
--tutorial
provides predefined styles to the app and the argument
--title "Tour of Pyroes"
is implicitly added
To get an an empty styles.css
file and set the title manually:
anpylar-application --htmlista --title "Tour of Pyroes" top0
Note
Because no extra option is passed, it’s like if --htmlista
had been
passed to the application component for generation
A directory named top0
will be created and populated. top0
stands
obviously for: Tour of Pyroes - Part 0
Note
If a directory/file named top0
already exists, the CLI won’t
do anything
The newly created top0
directory will contain the following files and
sub-directories:
├── app
│ ├── __init__.py
│ ├── app_component.css
│ ├── app_component.html
│ ├── app_component.py
│ └── app_module.py
├── anpylar.js
├── index.html
├── package.json
└── styles.css
Which will be already functional. With the addition of the --title "Tour of
Pyroes"
switch a title will be added to the main component. More on this
later.
Let’s get our hands dirty by serving the application:
anpylar-serve top0
which will output:
Sun Dec 3 08:51:47 2027 Server Starts - http://127.0.0.1:2222
Because no port has been specified the default port 2222
. The full URL to
access the sample is displayed, which can be pasted in the browser.
Note
You can also issue a:
anpylar-serve --browser top0
And AnPyLar will do everything in its power to open the browser for you
The server takes care already of delivering the index.html
file and the
result
Let’s look at the code and how we can modify the title of our application. The
app_component.py
contains the following code
<h1 {title}=title>{title}</h1>
from anpylar import Component, html
class AppComponentComponent(Component):
title = 'Tour of Pyroes'
bindings = {}
def render(self, node):
pass
Have a look at them before carrying on.
Note
There is a default render(self, node)
method generated which is
intended for direct DOM manipulation/generation. It can be suppressed
with --htmlista
. We have left it place, because it can always be
handy.
If we wanted a different title, it is obvious that we simply have to modify the
attribute title
in AppComponent
with the desired value as in:
title = 'My Tour of Pyroes'
<h1 {title}=title>{title}</h1>
Let’s look at the code inside the <h1>
tab
{title}=title
. This is telling the<h1>
node, that inside its text content a formatting operation will take place. Namely
{title}
in the text content will be formatted usingself.title
.Although
self
is not seen, everything in the attribute’s value is run in the context of the component and therefore the=title
will be handled as=self.title
The syntax inside the text content:
{title}
is the standard from theformat
built-in and string method of Python. Nothing new to learn here.
The project is live and therefore transpilation takes place by simple reloading the page in browser. And the result:
Some explaining¶
The loading¶
A simple look at AppComponent
and modifying title
doesn’t tell us much,
so let’s try to explain what’s happening by first looking into index.html
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<script src="anpylar.js"></script>
<title>AnPyLar Tour of Pyroes</title>
</head>
<body></body>
</html>
As with many other html documents, this one sets the title, some meta values
for the browser, loads the stylesheet, it then loads the needed a script
anpylar.js
which sets the AnPyLar machinery in place and will start it.
The execution¶
If no Python snippets or links to them are specified, AnPyLar will do the following for you
import app
app.AppModule()
This can of course be overridden by the end user by providing specific python
scripts which will kickstart the application. But this matches the code
auto-generated by the anpylar
cli.
We have seen above that things are triggered because an instance of
AppModule
is being triggered itself, so let’s look into it. One can
obviously find AppModule
inside the :file:app/app_module.py
(consistent
naming conventions … do actually help)
from anpylar import Module
from .app_component import AppComponent
class AppModule(Module):
components = AppComponent
bindings = {}
services = {}
routes = []
def __init__(self):
pass
Fairly simple, so let’s concentrate on components = [AppComponent]
.
This is telling
AppModule
that it should bootstrapAppComponent
during initialization.Note
components
is plural because it could also be a list/tuple with several items to be bootstrapped during initialization
The rest of items will be needed with more complex setups, but are auto-generated by the cli.
We can also have a look into __init__.py
which is the standard entry point
in Python packages.
from app import AppModule
It is simply making AppModule
available for the world and specifically in
this case, this is being used in index.html
to kick-start the entire
system.
Coming back to AppComponent
¶
Our component has no html code or specific styling built-in, but the project layout shows three files that seem to be related:
├── app
. ...
│ ├── app_component.css
│ ├── app_component.html
│ ├── app_component.py
. ...
And indeed, they are.
Inside
app_component.py
we have definedAppComponent
. It could have had any name, but as pointed out above: consistent naming conventions do help!And with the default configuration of our component, the following will happen behind the scenes:
A base filename
app_component
is derived from the class nameAppComponent
.The rules are easy: place
_
(underscore) signs at the boundary between lower and upper-case letters and then lowercase the resultWhen the component is being loaded:
app_component.css
will be loaded and the resulting styles used inside the component (you can actually find it under the<head>
tag, following html standards)
app_component.html
will be loaded and prepared as a set of DOM nodes. This result will be passed to therender(node)
method, for the end user to be able to manipulate the nodes.Note
this is not used in this case, because we are in the Htmlista mode and trying therefore to do all the rendering inside the html code itself
In our top0
tutorial, there are no specific styles for the component and
app_component.css
is empty.
Although the example is rather short it already shows several of the powers of a Component when developing with AnPyLar.
Some notes¶
If you have been working with some other platforms, including Angular, you may have noticed a couple of things:
Selector
There is no selector
being defined in AppComponent
Actually, there is and you as end user can define it as in
class AppComponent(Component):
selector = 'my-selector'
AnPyLar tries to make your life easier by auto-generating the
selector
if you provide none. See the resulting DOM elements
In this case the auto-generated selector is clearly named:
app-component-2
. Easy naming. If you wonder why the suffix -2
, this is
simply to avoid another AppComponent
(which could exist in another .py
file) overwrote our selector, because it will get assigned another -x
Filenames
There is no indication that the html of the component is in a file named
app_component.html
(and the same with styles and app_component.css
)
Actually, there is and you can change it. Subclasses of Component
inherit two attributes (see the reference documentation) which control
this. They look like this:
class Component:
htmlpath = True
stylepath = True
By being set to True
the default behavior is to look for the
aforementioned files for a component named AppComponent
, but you can
change that by doing this
class Component:
htmlpath = 'my_app_component.htmlx'
stylepath = 'mystyles/my_app_component.css'
And those will be the filenames to be fetched. Note how paths and own extensions can be specified. AnPyLar will make no effort to check the validity of those.