An extension that includes Materialize CSS (http://materializecss.com/) in your project, without any boilerplate code.
pip install Flask-Materialize==0.2.4
Flask-Materialize packages MaterializeCSS
https://github.com/Dogfalo/materialize into an extension that mostly consists
of a blueprint named 'material'. It can also create links to serve Materialize
from a CDN and works with no boilerplate code in your application.
Materialise has recently moved from 0.100 to version 1.0.0 RC 2, and this extension updates the original extension to this latest version. It also updates the version of jQuery loaded by the extension from 1.11 to 3.3.1
First, easily install the package with pip install flask-material
A sample helloworld app:
hello_world.py
Yes, I know this is a long helloworld, but, you'll have a great base to start with if you follow along!
from flask import Flask, render_template
from flask_materialize import Material
from flask_wtf import Form, RecaptchaField
from flask_wtf.file import FileField
from wtforms import TextField, HiddenField, ValidationError, RadioField,\
BooleanField, SubmitField, IntegerField, FormField, validators
from wtforms.validators import Required
app = Flask(__name__)
Material(app)
app.config['SECRET_KEY'] = 'USE-YOUR-OWN-SECRET-KEY-DAMNIT'
app.config['RECAPTCHA_PUBLIC_KEY'] = 'TEST'
# straight from the wtforms docs:
class TelephoneForm(Form):
country_code = IntegerField('Country Code', [validators.required()])
area_code = IntegerField('Area Code/Exchange', [validators.required()])
number = TextField('Number')
class ExampleForm(Form):
field1 = TextField('First Field', description='This is field one.')
field2 = TextField('Second Field', description='This is field two.',
validators=[Required()])
hidden_field = HiddenField('You cannot see this', description='Nope')
recaptcha = RecaptchaField('A sample recaptcha field')
radio_field = RadioField('This is a radio field', choices=[
('head_radio', 'Head radio'),
('radio_76fm', "Radio '76 FM"),
('lips_106', 'Lips 106'),
('wctr', 'WCTR'),
])
checkbox_field = BooleanField('This is a checkbox',
description='Checkboxes can be tricky.')
# subforms
mobile_phone = FormField(TelephoneForm)
# you can change the label as well
office_phone = FormField(TelephoneForm, label='Your office phone')
ff = FileField('Sample upload')
submit_button = SubmitField('Submit Form')
def validate_hidden_field(form, field):
raise ValidationError('Always wrong')
@app.route('/')
def hello_world():
form = ExampleForm()
return render_template('test.html', form = form)
if __name__ == '__main__':
app.run(debug = True)
templates/test.html with silly macros
{% extends "material/base.html" %}
{% import "material/utils.html" as util %}
{% import "material/wtf.html" as wtf %}
{% block title %}Hello, world!{% endblock %}
{% block content %}
{{ container() }}
{{ row() }}
{{ col(['s12', 'm6']) }}
{{ util.card('Hello world!', wtf.quick_form(form) )}}
{{ enddiv() }}
{{ col(['s12', 'm6'])}}
{{ util.card('Isn\'t Flask great?', '<p>I really do enjoy it!</p>', [['https://bitbucket.org/cyberspy/flask_materialize', 'My Bitbucket']])}}
{{ enddiv() }}
{{ enddiv() }}
{{ enddiv() }}
{% endblock %}
OR templates/test.html without silly macros
{% extends "material/base.html" %}
{% import "material/utils.html" as util %}
{% import "material/wtf.html" as wtf %}
{% block title %}Hello, world!{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col s12 m6">
{{ util.card('Hello world!', wtf.quick_form(form) )}}
</div>
<div class="col s12 m6">
{{ util.card('Isn\'t Flask great?', '<p>I really do enjoy it!</p>', [['https://bitbucket.org/cyberspy/flask_materialize', 'My Bitbucket']])}}
</div>
</div>
</div>
{% endblock %}
This makes some new templates available, containing blank pages that include all Material resources, and have predefined blocks where you can put your content.
{{block doc}}
Starts: Above <!DOCTYPE html>
Ends: Below </html>
{{block html_attribs}}
Starts: Inside the <html>
tag
Ends: Inside the <html>
tag
{{block head}}
Starts: Just after the <head>
tag
Ends: Just before the </head>
tag
{{block title}}
Starts: Just inside the <title>
tag
Ends: Before </title>
tag
{{block metas}}
Starts: Inside the <head>
block, after </title>
. Automatically includes
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Be sure to call super() if you want this meta tag
Ends: Within <head>
block, just before {{block styles}}
{{block styles}}
Starts: Inside the head block, after the metas
block closes. Includes a link to material.css,
Material Icons and Roboto - both as web fonts from Google. Be sure to include {{ super() }}
Ends: Just before </head>
{{block body_attribs}}
Starts: Just after <body
Ends: Just before >
in the top <body>
tag.
<body{% block body_attribs %}{% endblock body_attribs %}>
{{block body}}
Starts: Immediately after <body>
Contains: {{block navbar}}
Contains: {{block content}}
Contains: {{block scripts}}
which includes materialize.js and jquery.js, be sure to include {{ super() }}
Contains: {{block footer}}
Ends: Just above </body>
Be sure you are using {% import "material/utils.html" as util %}
in your HTML document.
Icon
Simply do: {{ util.icon('ICON-NAME-WITHOUT-MDI', ['SIZE', 'OPTIONAL-CSS-CLASSES']) }}
Button
Macro prototype: {{ util.form_button(content, class = [], type='submit', name='action', icon = False, iconclass=[] }}
**Note**
Class already includes btn. Everything else must be added.
<button class="btn {{ class|join(' ') }}" type="{{type}}" name="{{name}}">{{content}}
{% if icon %}<i class="{{ iconclass|join(' ') }} right"></i>{% endif %}</button>
Card
Card prototype: {{ util.card('CARD-TITLE', 'CARD-CONTENT-CAN-USE-HTML-HERE', [['http://google.com/LINK.html', 'Link Title'], ['http://www.google.co.uk/link2.html', 'Link Title2']]) }}
Card does not include any row, or column sizes. You must wrap the card in your desired size.
**These may or may not be useful, feedback requested. **
Container
{{ container() }}
Generates <div class="container">
Row
{{ row() }}
Generates <div class="row">
Col
{{ col( ['s12', 'm6'] ) }}
Generates <div class="col s12 m6">
Enddiv
{{ enddiv() }}
Generates </div>
This is largely a fork from the excellent work at https://github.com/mbr/flask-bootstrap and https://github.com/HellerCommaA/flask-materialize