Commit faf847ea authored by colmoneill's avatar colmoneill

Merge branch 'master' of gitlab.com:bemaker/eu.bemaker.flask

parents e8d181cb a41875ce
......@@ -8,6 +8,7 @@ from flask_security import Security, MongoEngineUserDatastore, UserMixin, RoleMi
from flask_login import user_logged_in
from flask_mail import Mail
from flask_mail import Message
from flask_security.forms import RegisterForm, StringField
from wtforms.validators import DataRequired
import urllib.request as ur
......@@ -24,7 +25,7 @@ from flask_admin import Admin
from flask_admin.form import rules
from flask_admin.contrib.mongoengine import ModelView, filters
from flask_admin.model.fields import InlineFormField, InlineFieldList
from wtforms import form, fields
# EVENTBRITE API
......@@ -155,7 +156,13 @@ def on_user_registered(sender, user, confirm_token):
def index():
eventbrite_json = ur.urlopen(eventbrite_url_requete)
events = json.loads(eventbrite_json.read().decode())
return render_template("home.html" , events=events)
articles = (p for p in pages if 'published' in p.meta)
print(articles)
# Show the 10 most recent articles, most recent first.
latest = sorted(articles, reverse=True,
key=lambda p: p.meta['published'])
return render_template("home.html" ,events=events ,articles=latest[:4])
@app.route("/learn")
def learn():
......@@ -201,7 +208,7 @@ def check_quiz(id):
ordering = json.loads(request.form['ord'])
quiz = copy.deepcopy(quizzes[id])
badge = quiz['badge']
print(badge)
# print(badge)
badge =str(badge)
quiz['questions'] = sorted(quiz['questions'], key=lambda q: ordering.index(quiz['questions'].index(q)))
answers = dict( (int(k), quiz['questions'][int(k)]['options'][int(v)]) for k, v in request.form.items() if k != 'ord' )
......@@ -242,10 +249,27 @@ def check_quiz(id):
return render_template('check_quiz.html', quiz=quiz, question_answer=zip(quiz['questions'], answers_list), correct=number_correct, total=len(answers_list))
@app.route("/contact")
def contact():
return render_template("contact.html")
return render_template('contact.html')
@app.route("/succes" , methods=["GET", "POST"])
def success():
if request.method == 'POST':
reply_to = request.form.get('email')
message = request.form.get('message')
subject = request.form.get('subject')
emailS = request.form.get('email')
message = subject + "\n" + message
print(message)
msg = Message(recipients=["julien@bemaker.eu"],
body = message,
subject = "contact from outer space (or website)",
sender = emailS )
mail.send(msg)
return render_template('succes.html')
@app.route("/event")
def event():
......@@ -265,7 +289,7 @@ def dashboard():
print('user: ' + C_user)
#db_user = User.objects.get(id=C_user).update(inc__dashboard_view_count=1, upsert=True)
message = 'Welcome to your dashboard ' + current_user.get_id()
flash(message)
flash(message , "alert-info")
return render_template('dashboard.html', user=C_user)
def inaccessible_callback(self, name, **kwargs):
......
......@@ -2,6 +2,8 @@ import re
import sys
from yaml import load, dump
import yaml
import os
inputMd = open( sys.argv[1] , 'r')
fileName = sys.argv[1].partition('.')
......
This diff is collapsed.
......@@ -17,6 +17,31 @@ h1, h2, h3, h4, h5 {
font-weight: bolder;
}
.material-icons.md-18 {
font-size: 18px;
vertical-align: middle;
}
.material-icons.md-24 {
font-size: 24px;
vertical-align: middle;
}
.material-icons.md-36 {
font-size: 36px;
vertical-align: middle;
}
.material-icons.md-48 {
font-size: 48px;
vertical-align: middle;
}
.material-icons.md-100 {
font-size: 100px;
vertical-align: middle;
}
input[type=radio] {
background: #FF0000;
border: none;
......@@ -27,6 +52,96 @@ input[type=radio]:checked {
border: RED;
}
#myBtn {
display: none;
/* Hidden by default */
position: fixed;
/* Fixed/sticky position */
bottom: 20px;
/* Place the button at the bottom of the page */
right: 30px;
/* Place the button 30px from the right */
z-index: 99;
/* Make sure it does not overlap */
border: none;
/* Remove borders */
outline: none;
/* Remove outline */
background-color: #eaeaea;
/* Set a background color */
color: white;
/* Text color */
cursor: pointer;
/* Add a mouse pointer on hover */
padding: 15px;
/* Some padding */
border-radius: 10px;
/* Rounded corners */
font-size: 18px;
/* Increase font size */
}
#myBtn:hover {
background-color: #555;
/* Add a dark-grey background on hover */
}
.panel {
position: fixed;
left: -15.625em;
/*left or right and the width of your navigation panel*/
width: 15.625em;
/*should match the above value*/
background: white;
z-index: 1000;
}
.panel ul {
list-style: none;
margin-left: 0;
padding-left: 0;
}
.panel ul li .logo {
margin: auto;
margin: auto !important;
display: block;
margin-top: 20px;
height: 80px;
}
.panel ul li {
font-size: 22px;
padding-right: 34px;
text-align: right;
}
.panel ul li a {
color: #333;
}
.panel ul li:first-child {
padding-left: 0 !important;
margin-left: 0 !important;
}
.menu-link {
display: none;
position: fixed;
top: 10px;
left: 10px;
width: 40px;
height: 40px;
font-size: 24px;
color: #fff;
z-index: 900;
background: #17a2b8;
border-radius: 3px;
text-align: center;
line-height: 40px;
}
.menu-link:hover {
text-decoration: none;
box-shadow: 1px 1px 0px #1592a6, -2px -2px 0px #148a9d, -3px -3px 0px #128294, -4px -4px 0px #117a8b, -5px -5px 0px #107282, -6px -6px 0px #0f6a79;
top: 16px;
left: 16px;
}
.no-gutter {
margin: 0;
padding: 0;
......@@ -435,4 +550,14 @@ footer {
height: 200px;
}
@media only screen and (max-width: 825px) {
#menuMain, #menuSecond {
display: none;
}
.menu-link {
display: block;
}
}
/*# sourceMappingURL=style.css.map */
......@@ -20,6 +20,11 @@ h1, h2, h3, h4, h5 {
font-weight: bolder;
// text-align: center;
}
.material-icons.md-18 { font-size: 18px;vertical-align: middle; }
.material-icons.md-24 { font-size: 24px;vertical-align: middle; }
.material-icons.md-36 { font-size: 36px; vertical-align: middle;}
.material-icons.md-48 { font-size: 48px; vertical-align: middle;}
.material-icons.md-100 { font-size: 100px; vertical-align: middle;}
input[type="radio"] {
background: #FF0000;
......@@ -30,8 +35,88 @@ input[type="radio"]:checked{
border: RED;
}
#myBtn {
display: none; /* Hidden by default */
position: fixed; /* Fixed/sticky position */
bottom: 20px; /* Place the button at the bottom of the page */
right: 30px; /* Place the button 30px from the right */
z-index: 99; /* Make sure it does not overlap */
border: none; /* Remove borders */
outline: none; /* Remove outline */
background-color: #eaeaea; /* Set a background color */
color: white; /* Text color */
cursor: pointer; /* Add a mouse pointer on hover */
padding: 15px; /* Some padding */
border-radius: 10px; /* Rounded corners */
font-size: 18px; /* Increase font size */
}
#myBtn:hover {
background-color: #555; /* Add a dark-grey background on hover */
}
.panel {
position: fixed;
left: -15.625em; /*left or right and the width of your navigation panel*/
width: 15.625em; /*should match the above value*/
background: white;
z-index: 1000;
ul {
list-style: none;
margin-left: 0;
padding-left: 0;
li .logo{
margin: auto;
margin: auto !important;
display: block;
margin-top: 20px;
height: 80px;
}
li{
font-size: 22px;
padding-right: 34px;
text-align: right;
a{
color: #333;
}
&:first-child{
padding-left: 0!important;
margin-left: 0!important;
}
}
}
}
.menu-link {
display: none;
position:fixed;
top:10px;
left:10px;
width: 40px ;
height: 40px;
font-size:24px;
color: #fff;
z-index: 900;
background: #17a2b8;
border-radius: 3px;
text-align: center;
line-height: 40px;
&:hover{
text-decoration: none;
box-shadow: 1px 1px 0px darken( #17a2b8, 4% ),
-2px -2px 0px darken( #17a2b8, 6% ),
-3px -3px 0px darken( #17a2b8, 8% ),
-4px -4px 0px darken( #17a2b8, 10% ),
-5px -5px 0px darken( #17a2b8, 12% ),
-6px -6px 0px darken( #17a2b8, 14% );
top:16px;
left:16px;
}
}
.no-gutter {
margin: 0;
padding: 0;
......@@ -469,3 +554,15 @@ footer {
background: #2c3e50;
height: 200px;
}
@media only screen and (max-width: 825px){
#menuMain , #menuSecond{
display: none;
}
.menu-link{
display: block;
}
}
/*! bigSlide - v0.12.0 - 2016-08-01
* http://ascott1.github.io/bigSlide.js/
* Copyright (c) 2016 Adam D. Scott; Licensed MIT */
!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){"use strict";function b(a,b){for(var c,d=a.split(";"),e=b.split(" "),f="",g=0,h=d.length;h>g;g++){c=!0;for(var i=0,j=e.length;j>i;i++)(""===d[g]||-1!==d[g].indexOf(e[i]))&&(c=!1);c&&(f+=d[g]+"; ")}return f}a.fn.bigSlide=function(c){var d=this,e=a.extend({menu:"#menu",push:".push",shrink:".shrink",hiddenThin:".hiddenThin",side:"left",menuWidth:"15.625em",semiOpenMenuWidth:"4em",speed:"300",state:"closed",activeBtn:"active",easyClose:!1,saveState:!1,semiOpenStatus:!1,semiOpenScreenWidth:480,beforeOpen:function(){},afterOpen:function(){},beforeClose:function(){},afterClose:function(){}},c),f="transition -o-transition -ms-transition -moz-transitions webkit-transition "+e.side,g={menuCSSDictionary:f+" position top bottom height width",pushCSSDictionary:f,state:e.state},h={init:function(){i.init()},_destroy:function(){return i._destroy(),delete d.bigSlideAPI,d},changeState:function(){"closed"===g.state?g.state="open":g.state="closed"},setState:function(a){g.state=a},getState:function(){return g.state}},i={init:function(){this.$menu=a(e.menu),this.$push=a(e.push),this.$shrink=a(e.shrink),this.$hiddenThin=a(e.hiddenThin),this.width=e.menuWidth,this.semiOpenMenuWidth=e.semiOpenMenuWidth;var b={position:"fixed",top:"0",bottom:"0",height:"100%"},c={"-webkit-transition":e.side+" "+e.speed+"ms ease","-moz-transition":e.side+" "+e.speed+"ms ease","-ms-transition":e.side+" "+e.speed+"ms ease","-o-transition":e.side+" "+e.speed+"ms ease",transition:e.side+" "+e.speed+"ms ease"},f={"-webkit-transition":"all "+e.speed+"ms ease","-moz-transition":"all "+e.speed+"ms ease","-ms-transition":"all "+e.speed+"ms ease","-o-transition":"all "+e.speed+"ms ease",transition:"all "+e.speed+"ms ease"},g=!1;b[e.side]="-"+e.menuWidth,b.width=e.menuWidth;var j="closed";e.saveState?(j=localStorage.getItem("bigSlide-savedState"),j||(j=e.state)):j=e.state,h.setState(j),this.$menu.css(b);var k=a(window).width();"closed"===j?e.semiOpenStatus&&k>e.semiOpenScreenWidth?(this.$hiddenThin.hide(),this.$menu.css(e.side,"0"),this.$menu.css("width",this.semiOpenMenuWidth),this.$push.css(e.side,this.semiOpenMenuWidth),this.$shrink.css({width:"calc(100% - "+this.semiOpenMenuWidth+")"}),this.$menu.addClass("semiOpen")):this.$push.css(e.side,"0"):"open"===j&&(this.$menu.css(e.side,"0"),this.$push.css(e.side,this.width),this.$shrink.css({width:"calc(100% - "+this.width+")"}),d.addClass(e.activeBtn));var l=this;d.on("click.bigSlide touchstart.bigSlide",function(a){g||(l.$menu.css(c),l.$push.css(c),l.$shrink.css(f),g=!0),a.preventDefault(),"open"===h.getState()?i.toggleClose():i.toggleOpen()}),e.semiOpenStatus&&a(window).resize(function(){var b=a(window).width();b>e.semiOpenScreenWidth?"closed"===h.getState()&&(l.$hiddenThin.hide(),l.$menu.css({width:l.semiOpenMenuWidth}),l.$menu.css(e.side,"0"),l.$push.css(e.side,l.semiOpenMenuWidth),l.$shrink.css({width:"calc(100% - "+l.semiOpenMenuWidth+")"}),l.$menu.addClass("semiOpen")):(l.$menu.removeClass("semiOpen"),"closed"===h.getState()&&(l.$menu.css(e.side,"-"+l.width).css({width:l.width}),l.$push.css(e.side,"0"),l.$shrink.css("width","100%"),l.$hiddenThin.show()))}),e.easyClose&&a(document).on("click.bigSlide",function(b){a(b.target).parents().addBack().is(d)||a(b.target).closest(e.menu).length||"open"!==h.getState()||i.toggleClose()})},_destroy:function(){this.$menu.each(function(){var c=a(this);c.attr("style",b(c.attr("style"),g.menuCSSDictionary).trim())}),this.$push.each(function(){var c=a(this);c.attr("style",b(c.attr("style"),g.pushCSSDictionary).trim())}),this.$shrink.each(function(){var c=a(this);c.attr("style",b(c.attr("style"),g.pushCSSDictionary).trim())}),d.removeClass(e.activeBtn).off("click.bigSlide touchstart.bigSlide"),this.$menu=null,this.$push=null,this.$shrink=null,localStorage.removeItem("bigSlide-savedState")},toggleOpen:function(){e.beforeOpen(),h.changeState(),i.applyOpenStyles(),d.addClass(e.activeBtn),e.afterOpen(),e.saveState&&localStorage.setItem("bigSlide-savedState","open")},toggleClose:function(){e.beforeClose(),h.changeState(),i.applyClosedStyles(),d.removeClass(e.activeBtn),e.afterClose(),e.saveState&&localStorage.setItem("bigSlide-savedState","closed")},applyOpenStyles:function(){var b=a(window).width();e.semiOpenStatus&&b>e.semiOpenScreenWidth?(this.$hiddenThin.show(),this.$menu.animate({width:this.width},{duration:Math.abs(e.speed-100),easing:"linear"}),this.$push.css(e.side,this.width),this.$shrink.css({width:"calc(100% - "+this.width+")"}),this.$menu.removeClass("semiOpen")):(this.$menu.css(e.side,"0"),this.$push.css(e.side,this.width),this.$shrink.css({width:"calc(100% - "+this.width+")"}))},applyClosedStyles:function(){var b=a(window).width();e.semiOpenStatus&&b>e.semiOpenScreenWidth?(this.$hiddenThin.hide(),this.$menu.animate({width:this.semiOpenMenuWidth},{duration:Math.abs(e.speed-100),easing:"linear"}),this.$push.css(e.side,this.semiOpenMenuWidth),this.$shrink.css({width:"calc(100% - "+this.semiOpenMenuWidth+")"}),this.$menu.addClass("semiOpen")):(this.$menu.css(e.side,"-"+this.width),this.$push.css(e.side,"0"),this.$shrink.css("width","100%"))}};return h.init(),this.bigSlideAPI={settings:e,model:g,controller:h,view:i,destroy:h._destroy},this}});
\ No newline at end of file
$( document ).ready(function() {
$('.menu-link').bigSlide({
easyClose : true
});
var imgBgnbr = 1 + Math.floor(Math.random() * 3);
var url = "url('img/"
var img = imgBgnbr.toString().concat("",".jpg");
url += img + "')!important";
$('head').append('<style> #bg:before {background-image:'+url+';} </style>');
$('.tutoItem').css('height', $('.tutoItem').width());
// $('.tutoItem').css('height', $('.tutoItem').width());
$('.desc p').click(function(){
$(this).toggleClass('openDiv')
......
......@@ -16,7 +16,7 @@
{% block nav %}
{% include 'menu.html'%}
{% endblock nav %}
<div class="pageWrap">
<div class="pageWrap push">
{% block content %}
{% endblock content %}
</div>
......@@ -26,6 +26,7 @@
<script src="{{ url_for('static', filename='node_modules/jquery/dist/jquery.min.js')}}"></script>
<script src="{{ url_for('static', filename='node_modules/bootstrap/dist/js/bootstrap.min.js')}}"></script>
<script src="{{ url_for('static', filename='js/bigSlide.min.js')}}"></script>
<script src="{{ url_for('static', filename='js/main.js')}}"></script>
</body>
</html>
......@@ -2,37 +2,33 @@
{% extends "base.html" %}
{% block content %}
<h1> contact us </h1>
<div class="container ">
<h1 style="text-align:center;">Contact</h1>
<dir class="row no-gutters justify-content-md-center">
<div class=" col col-12 col-sm-12 col-md-8 col-lg-8">
<div class="form-area">
<form role="form">
<div class="form-area">
<form role="form" method="POST" action="/succes">
<div class="form-group">
<input type="text" class="form-control" id="name" name="name" placeholder="Name" required>
<input type="text" class="form-control" id="name" name="name" placeholder="Name"required>
</div>
<div class="form-group">
<input type="text" class="form-control" id="email" name="email" placeholder="Email" required>
<input type="text" class="form-control" id="email" pattern="[^ @]*@[^ @]*" name="email" placeholder="Email" data-toggle="tooltip" data-placement="top" title=" format : yourname@domain.com" required>
</div>
<div class="form-group">
<input type="text" class="form-control" id="subject" name="subject" placeholder="Subject" required>
</div>
<div class="form-group">
<textarea class="form-control" type="textarea" id="message" placeholder="Message" maxlength="140" rows="7"></textarea>
<span class="help-block"><p id="characterLeft" class="help-block ">You have reached the limit</p></span>
</div>
<button type="button" id="submit" name="submit" class="btn btn-primary pull-right">Submit Form</button>
<div class="form-group">
<textarea class="form-control" type="textarea" name="message" placeholder="Message" maxlength="450" rows="7" required></textarea>
</div>
<button type="submit" id="submit" name="submit" class="btn btn-primary pull-right">send</button>
</form>
</div>
</dir>
</div>
</div>
{% endblock %}
\ No newline at end of file
{% endblock %}
......@@ -26,7 +26,7 @@
<h2>TES BADGES</h2>
<div class="row">
{% for badge, value in current_user.badges.items() %}
{{ value.lvl }}
<div class="col-2">
<div class="badgeItem">
{% if value.lvl == "1" %}
......@@ -44,16 +44,6 @@
</div>
{% endfor %}
<div class="col-2">
<div class="badgeItem">
<div class="badgeImg">
</div>
<span> maker </span>
</div>
</div>
</div>
</div>
</div>
......
......@@ -17,11 +17,29 @@
</div>
<div class="tutoWrapper">
<button onclick="topFunction()" id="myBtn" title="Go to top">Top</button>
<div class="tutoContent container">
<H1>LEARN</H1>
{{page}}
</div>
</div>
<script>
// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
document.getElementById("myBtn").style.display = "block";
} else {
document.getElementById("myBtn").style.display = "none";
}
}
// When the user clicks on the button, scroll to the top of the document
function topFunction() {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
}
</script>
{% endblock %}
......@@ -4,26 +4,28 @@
<div class=" col col-12 col-sm-12 col-md-6 col-lg-4">
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/horizontal-slim-10_7.css" rel="stylesheet" type="text/css">
<style type="text/css">
#mc_embed_signup{ clear:left; width:100%;}
/* Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<div id="mc_embed_signup">
<form action="https://bemaker.us17.list-manage.com/subscribe/post?u=cdd8dfbf90bd0195566431e2f&amp;id=e7e8df078e" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
<div id="mc_embed_signup_scroll">
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required>
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_cdd8dfbf90bd0195566431e2f_e7e8df078e" tabindex="-1" value=""></div>
<div class="clear"><input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button"></div>
</div>
<div class="spacer"></div>
<form action="https://bemaker.us17.list-manage.com/subscribe/post?u=cdd8dfbf90bd0195566431e2f&amp;id=e7e8df078e" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate form-group" target="_blank" novalidate>
<input type="email" value="" name="EMAIL" class="email form-control" id="mce-EMAIL" placeholder="newsletter" required>
<div class="spacer" style="height:10px;"></div>
<div style="position: absolute; left: -5000px;" aria-hidden="true">
<input type="text" name="b_cdd8dfbf90bd0195566431e2f_e7e8df078e" tabindex="-1" value=""></div>
<input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button form-control">
</form>
</div>
<div class=" col col-12 col-sm-12 col-md-6 col-lg-4">
<h4>PARTENAIRES</h4>
<ul>
<li>truc</li>
<li>truc</li>
<li>truc</li>
</ul>
</div>
<!--End mc_embed_signup-->
</div>
</div>
</div>
</div>
</div>
</footer>
\ No newline at end of file
</footer>
......@@ -5,5 +5,6 @@
<link href="{{ url_for('static', filename='css/style.css')}}" rel="stylesheet" media="screen">
<!-- LOAD MD CONTENT SPECIFIC CSS -->
<link href="{{ url_for('static', filename='css/mdcss.css')}}" rel="stylesheet" media="screen">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
{{path}}
\ No newline at end of file
{{path}}
......@@ -41,7 +41,9 @@
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 ">
<div class='cta'>
<div class="ico">
<img src="img/people.png">
<i class="material-icons md-100">
public
</i>
</div>
<h3>Inscription</h3>
<p>
......@@ -55,7 +57,9 @@
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 ">
<div class='cta'>
<div class="ico">
<img src="img/hat.png">
<i class="material-icons md-100">
local_bar
</i>
</div>
<h3>Decouvrir</h3>
<p>
......@@ -69,7 +73,9 @@
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 ">
<div class='cta'>
<div class="ico">
<img src="img/tools2.png">
<i class="material-icons md-100">
whatshot
</i>
</div>
<h3> Atelier </h3>
<p>
......@@ -98,90 +104,43 @@
<div class="homePush greyBg">
<h2>LEARN </h2>
<div class="container-fluid">
<div class="row no-gutter">
<div class="col col-12 col-sm-12 col-md-12 col-lg-12">
<div class="row">
<div class="col col-12 col-sm-6 col-md-4 col-lg-3 tutoItem">
<div class="tutoBox">
<img src="https://placeimg.com/640/480/tech">
<div class="overTuto green">
<h4>arduino first step</h4>
<span class="desc">Desciption courte</span>
</div>
</div>
</div>
<div class="col col-12 col-sm-6 col-md-4 col-lg-3 tutoItem">
<div class="tutoBox">
<img src="https://placeimg.com/640/480/tech">
<div class="overTuto red">
<h4>arduino first step</h4>
<span class="desc">Desciption courte</span>
</div>
</div>
</div>
<div class="col col-12 col-sm-6 col-md-4 col-lg-3 tutoItem">
<div class="tutoBox">
<img src="https://placeimg.com/640/480/tech">
<div class="overTuto green">
<h4>arduino first step</h4>
<span class="desc">Desciption courte</span>
</div>
</div>
</div>
<div class="col col-12 col-sm-6 col-md-4 col-lg-3 tutoItem">
<div class="tutoBox">
<img src="https://placeimg.com/640/480/tech">
<div class="overTuto green">
<h4>arduino first step</h4>
<span class="desc">Desciption courte</span>
</div>
</div>
</div>
<div class="col col-12 col-sm-6 col-md-4 col-lg-3 tutoItem">
<div class="tutoBox">
<img src="https://placeimg.com/640/480/tech">
<div class="overTuto blue">
<h4>arduino first step</h4>
<span class="desc">Desciption courte</span>
</div>
</div>
</div>
<div class="col col-12 col-sm-6 col-md-4 col-lg-3 tutoItem">
<div class="tutoBox">
<img src="https://placeimg.com/640/480/tech">
<div class="overTuto green">
<h4>arduino first step</h4>
<span class="desc">Desciption courte</span>
</div>
</div>
</div>
<div class="col col-12 col-sm-6 col-md-4 col-lg-3 tutoItem">
<div class="tutoBox">
<img src="https://placeimg.com/640/480/tech">
<div class="overTuto blue">
<h4>arduino first step</h4>
<span class="desc">Desciption courte</span>
</div>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row no-gutter">
<div class="col col-12 col-sm-12 col-md-12 col-lg-12">
<div class="row">
{% for article in articles %}
<div class="col col-12 col-sm-6 col-md-4 col-lg-3 tutoItem">
<div class="tutoBox">
<a href="/learn/{{article.path}}">
{% if article.featured_image %}
<img src="../static/{{article.featured_image}}">
<div class="overTuto {{ article.cat }}">
<h4>{{article.title}}</h4>
<span class="desc">{{article.desc}}</span>
</div>
{% else %}
<img src="../static/placeholder.jpg">
<div class="overTuto {{ article.cat }}">
<h4>{{article.title}}</h4>
<span class="desc">{{article.desc}}</span>
</div>
{% endif%}
</a>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
<div class="row center cta-btn">
<a href="/learn"> <button type="button" name="button" class="btn btn-info btn-lg text-center">all tuto</button></a>
</div>
</div>
</div>