With the recent addition of Google's Material Design Lite, this project will soon be ported over to that framework and change names. http://www.getmdl.io/ However, this project will be maintained in this repo and on PyPi. More updates will follow.
Flask-Material 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.
A quick demo applicdation can be seen at http://flask-template-materia.elasticbeanstalk.com/
This demo is a clone of https://github.com/HellerCommaA/flask-template-materialize
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_material 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://github.com/HellerCommaA', 'My Github']])}}
{{ 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://github.com/HellerCommaA', 'My Github']])}}
</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 be sure to call 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 call 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>
- Fix WTF forms integration (quick form)
- Finish documentation
This is largely a fork from the excellent work at https://github.com/mbr/flask-bootstrap