I'm installed and configured FOSUserBundle on my project (I'm using symfony 4). The installation is done without problem.
I override FOSUserBundle templates, but same that layout.html.twig and base.html.twig are not overrided.
My layout.html.twig :
{% extends 'base.html.twig' %}
{% block body %}
<div class="container">
<div class="row">
<div class="col-xs-12">
{% block fos_user_content %}{% endblock %}
</div>
</div>
</div>
{% endblock %}
My base.html.twig :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>
The only FOSUserBundle is used.
Secondly, the symfony debug toolbar is disappeared.
FOSUserBundle overrided there :
templates/bundles/FOSUserBundle
On the folder I added all FOSUserBundle sub folders:
Security
Registration
Profile
....
Template structure
This is how I have done it:
base.html.twig
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>
{% block title %}Admin panel{% endblock %}
</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="robots" content="noindex,nofollow"/>
<link rel="stylesheet" href="{{ asset('css/bootstrap.min.css') }}"/>
</head>
<body>
<div class="container">
{% block content %}{% endblock %}
</div>
<script src="{{ asset('js/jquery-3.3.1.min.js') }}"></script>
<script src="{{ asset('js/bootstrap.min.js') }}"></script>
</body>
</html>
layout.html.twig
{% extends 'bundles/FOSUserBundle/base.html.twig' %}
{% block content %}
{% if app.request.hasPreviousSession %}
{% for type, messages in app.session.flashbag.all() %}
{% for message in messages %}
<div class="flash-{{ type }}">
{{ message }}
</div>
{% endfor %}
{% endfor %}
{% endif %}
<div>
{% block fos_user_content %}
{% endblock fos_user_content %}
</div>
{% endblock %}
Security/login.html.twig
{% extends "bundles/FOSUserBundle/layout.html.twig" %}
{% trans_default_domain 'FOSUserBundle' %}
{% block title %}Sing in{% endblock %}
{% block fos_user_content %}
<div class="jumbotron">
<h4 class="text-center">Sign in</h4>
{% if error %}
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<form method="post" action="{{ path("fos_user_security_check") }}">
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}"/>
<div class="form-group">
<label for="username">Email:</label>
<input type="email" name="_username" class="form-control" id="username" value="{{ last_username }}"
autocomplete="off">
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" id="password" name="_password" class="form-control">
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" id="remember_me" name="_remember_me" value="on">Remember
me
</label>
</div>
<button name="_submit" type="submit" class="btn btn-primary">{{ 'security.login.submit'|trans }}</button>
</form>
</div>
{% endblock fos_user_content %}
Related
I would like to override the FOSuser login_content template but Symfony returns this error : Screen of the error
Twig can't find the variable error. So I replaced {% if error %} by {% if error is defined %} just as this answer tell to do : Variable "error" does not exist in FOSUserBundle::layout.html.twig at line 5
It removes the error for the variable "error" but now it returns exactly the same error with the variable "csrf_token".
I imagine that there is a better solution than adding "is defined" everywhere.
For now I just create files in FOSuserBundle/views in app/Resources with the exact name of the files I want to override.
The error occurs when I am log out and I try to access a page which as a restricted access. If I try to go on the login page, I do have the login form and I can log in.
It looks like a route error but I can't find where
Here is my code :
{# app\Resources\FOSUserBundle\views\Security\login_content.html.twig #}
{% trans_default_domain 'FOSUserBundle' %}
{% if error %}
<div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<form action="{{ path("fos_user_security_check") }}" method="post">
{% if csrf_token %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" />
{% endif %}
<div class="form-group">
<label for="username">{{ 'security.login.username'|trans }}</label>
<input type="text" id="username" name="_username" value="{{ last_username }}" required="required" class="form-control"/>
</div>
<div class="form-group">
<label for="password">{{ 'security.login.password'|trans }}</label>
<input type="password" id="password" name="_password" required="required" class="form-control"/>
</div>
<div class="checkbox">
<label for="remember_me">
<input type="checkbox" id="remember_me" name="_remember_me" value="on" />
{{ 'security.login.remember_me'|trans }}
</label>
</div>
<input type="submit"
class ="btn btn-success"
id="_submit"
name="_submit"
value="{{ 'security.login.submit'|trans }}" />
</form>
This code is called here :
{# app\Resources\FOSUserBundle\views\Security\login.html.twig #}
{% extends "#FOSUser/layout.html.twig" %}
{% block fos_user_content %}
{{ include('#FOSUser/Security/login_content.html.twig') }}
{% endblock fos_user_content %}
which extends :
{# app\Resources\FOSUserBundle\views\layout.html.twig #}
{% extends '#OCCore/layout.html.twig' %}
{% block content %}
<div>
{% if is_granted("IS_AUTHENTICATED_REMEMBERED") %}
{{ 'layout.logged_in_as'|trans({'%username%': app.user.username}, 'FOSUserBundle') }} |
<a href="{{ path('fos_user_security_logout') }}">
{{ 'layout.logout'|trans({}, 'FOSUserBundle') }}
</a>
{% else %}
{{ 'layout.login'|trans({}, 'FOSUserBundle') }}
{% endif %}
</div>
{% if app.request.hasPreviousSession %}
{% for type, messages in app.session.flashbag.all() %}
{% for message in messages %}
<div class="flash-{{ type }}">
{{ message }}
</div>
{% endfor %}
{% endfor %}
{% endif %}
<div>
{% block fos_user_content %}
{% endblock fos_user_content %}
</div>
{% endblock %}
which extends :
{# src/OC/CoreBundle/Resources/views/layout.html.twig #}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}Auréole{% endblock %}</title>
{% block stylesheets %}
{# On charge le CSS de bootstrap depuis le site directement #}
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
{% endblock stylesheets %}
</head>
<body>
{% include 'top-navbar.html.twig' %} {#cherche la navbar \app\Resources\views\navbar.html.twig #}
<div class="container">
<div id="header" class="jumbotron">
<h1>Auréole</h1>
<p>
Auréole est un projet d'Enactus Centralesupelec
</p>
<p>
<a class="btn btn-primary btn-lg" href="https://www.facebook.com/EnactusCS/">
Retrouvez nous sur Facebook
</a>
</p>
</div>
<div class="row">
<div id="menu" class="col-md-3">
<h3>Les annonces</h3>
<ul class="nav nav-pills nav-stacked">
<li>Accueil</li>
{% if is_granted('ROLE_AUTEUR') %}
<li>Ajouter une annonce</li>
{% endif %}
</ul>
</div>
<div id="content" class="col-md-9">
{% block body %}
{% endblock %}
</div>
</div>
<hr>
<footer>
<p>Born to be Wild © {{ 'now'|date('Y') }}.</p>
</footer>
</div>
{% block javascripts %}
{# Ajoutez ces lignes JavaScript si vous comptez vous servir des fonctionnalités du bootstrap Twitter #}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
{% endblock %}
</body>
</html>
As I was trying to customize a login form fro FosUSerBundle of my symfony 3 project, therefore I had a look on the FosUSerBundle's default twig templates in order to gen an idea, then I noticed that the twig template provided via vendor (vendor/friendsofsymfony/user-bundle/Resources/views/Registration/register_content.html.twig) has the following values:
{% trans_default_domain 'FOSUserBundle' %}
{{ form_start(form, {'method': 'post', 'action': path('fos_user_registration_register'), 'attr': {'class': 'fos_user_registration_register'}}) }}
{{ form_widget(form) }}
<div>
<input type="submit" value="{{ 'registration.submit'|trans }}" />
</div>
{{ form_end(form) }}
And I noticed that it calls a {{ form_widget(form) }} in order to render the form. so I want to know how this method is called and how can I customize the view. Basically I want the and the html classes of the form in order to look like the registration admin AdminLte's One: https://almsaeedstudio.com/themes/AdminLTE/pages/examples/register.html
Right now what I have done is to create this template app/Resources/FOSUSerBundle/views/Registration/register.html.twig:
{% extends "FOSUserBundle::layout.html.twig" %}
{% set classes='hold-transition register-page'%}
{% block fos_user_content %}
{% trans_default_domain 'FOSUserBundle' %}
<div class="register-box">
<div class="register-logo">
<h1>PhotoShare!</h1>
</div>
<div class="register-box-body">
<p class="login-box-msg">Register a new membership</p>
{{ form_start(form, {'method': 'post', 'action': path('fos_user_registration_register')}) }}
{{ form_widget(form) }}
<div class="row">
<div class="col-xs-4">
<input type="submit" class="btn btn-primary btn-block btn-flat" value="{{ 'registration.submit'|trans }}" />
</div>
</div>
{{ form_end(form) }}
</div>
{% endblock fos_user_content %}
That extends app/Resources/FOSUSerBundle/views/layout.html.twig has the following content:
{% extends '::base.html.twig' %}
{% block title %}Photoshare!!{% endblock %}
{% set classes=''%}
{% block body %}
{% block fos_user_content %}
{% endblock fos_user_content %}
{% endblock body %}
That extends the app/Resourses/views/base.html.twig template:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% block stylesheets %}
<link rel="stylesheet" type="text/css" href="{{asset('assets/vendor/bootstrap/css/bootstrap.css')}}" >
<link rel="stylesheet" type="text/css" href="{{asset('assets/vendor/adminlte/adminlte.css')}}" >
<link rel="stylesheet" type="text/css" href="{{asset('assets/vendor/adminlte/skin-blue.css')}}" >
{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
{% block javascriptsHeader %}
{% endblock %}
</head>
<body class="{{ classes }}">
{% block body %}
{% endblock body %}
{% block javascriptsFooter %}
{% endblock javascriptsFooter %}
</body>
</html>
The fields I want to render are the default and the very same that are provided via the default FosUserBundle's administrator form. I want to mess around with the html classes in order to achieve the same look from the template that is mentioned above.
A form theme is what you need.
You can either create a form theme and use it only in specific templates like your registration form:
{% form_theme form 'register-form-theme.html.twig' %}
{% trans_default_domain 'FOSUserBundle' %}
{{ form_start(form, {'method': 'post', 'action': path('fos_user_registration_register'), 'attr': {'class': 'fos_user_registration_register'}}) }}
{{ form_widget(form) }}
<div>
<input type="submit" value="{{ 'registration.submit'|trans }}" />
</div>
{{ form_end(form) }}
Or you can set a global form theme in config.yml:
# Twig Configuration
twig:
# ...
form_themes:
- 'form-theme.html.twig'
Your form theme then should extend the default div layout provided by symfony:
{% extends 'form_div_layout.html.twig' %}
You can then override the blocks from this template:
{# app/Resources/views/form-theme.html.twig #}
{% extends 'form_div_layout.html.twig' %}
{%- block form_start -%}
{% set attr = attr|merge({ 'class': (attr.class|default('') ~ ' custom classes')|trim }) %}
{{ parent() }}
{%- endblock form_start -%}
{%- block form_row -%}
<div class="custom classes">
{{- form_label(form) -}}
{{- form_widget(form) -}}
{{- form_errors(form) -}}
</div>
{%- endblock form_row -%}
{%- block form_widget_simple -%}
{% set attr = attr|merge({ 'class': (attr.class|default('') ~ ' custom classes')|trim }) %}
{{ parent() }}
{%- endblock form_widget_simple -%}
I have added some of the variables in base.html.twig file
I have another file index.html.twig file in "bundle"
I have extended base.html.twig file in index.html.twig which is working fine as I am able to see all content in base is rendered in browser when i am calling index.html.twig, but when i try to override variables of base.html.twig file from index.html.twig its not working
here is code
base.html.twig
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}
{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('favicon') }}" />
</head>
<body>
{% set isHeader = (isHeader|default(true)) %}
{% if isHeader == true %}
<div class="container-fluid header">
{% include 'header.html.twig' %}
{% block header %}
{% endblock %}
</div>
{% endif %}
</body>
</html>
index.html.twig
{% extends 'base.html.twig' %}
{% set isHeader = false %}
this should hide header but its still displaying header where as if I do isHeader = false in base.html.twig file it works fine
your method is too weird , i'm not sure why are you doing this ,
According to what I found from question , try to do something like this :
in base :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}
{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('favicon') }}" />
</head>
<body>
{%block top_header %}
<div class="container-fluid header">
{% include 'header.html.twig' %}
{% block header %}
{% endblock %}
</div>
{%endblock%}
</body>
</html>
in index :
{% extends 'base.html.twig' %}
{% block top_header %}{% endblock %} //keep this empty , remove the top_header content
I found answer by setting global for twig in symfony config.yml file here is code
config.yml
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
globals:
isFooter: true
isHeader: true
base.html.twig
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
<link rel="icon" type="image/x-icon" href="{{ asset('favicon') }}" />
</head>
<body>
{% if isHeader == true %}
<div class="container-fluid header">
{% include 'header.html.twig' %}
{% block header %}
{% endblock %}
</div>
{% endif %}
{% block body %}
{% endblock %}
{% if isFooter == true %}
<div class="footer">
{% include 'footer.html.twig' %}
{% block footer %}
{% endblock %}
</div>
{% endif %}
<noscript><div class="alert alert-danger">You must enable Javascript on your browser for the site to work optimally and display sections completely.</div></noscript>
</body>
</html>
index.html.twig
{% set isFooter = true %}
{% set isHeader = false %}
{% block body %}
{% endblock %}
variable isHeader = false will remove header from base template so that it will not render on call of index.html.twig
Any other workaround guys please comment your suggestions.
I'm using Symfony2 to create a single page application,
as you can see, the base.html.twig (posted below) is relatively small,
all I want to do is create a route '/' that redirects directly to the base.html without the need of using unnecessary bundle inheritance.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %} Share with me {% endblock %}</title>
{% block stylesheets %}
{% include 'assets/basetemplates.html.twig' %}
{% endblock %}
</head>
<body class="metro mybody">
{% block channel %}
<div id="profile_push_container"></div>
<a href="#channel-close">
<div class="profile-modal-overlay"></div>
</a>
{% endblock %}
{% block content_form %}
<div id="content_form_overlay" class="animated fadeIn"></div>
<div id="content_form" class="animated fadeInDownBig">
<div class="content_form">
<button class="content_cancel_btn" onclick="ContentForm.controller.closeForm();"><i class="icon-cancel-2"></i></button>
<div class="form-items" id="form-items">
<div class="form-item">
<h2 class="content_title">Auto handel</h2>
</div>
</div>
</div>
</div>
{% endblock %}
{% block navbar %}
{% include 'GabrielLayoutBundle:Widgets:navigation.html.twig' %}
{% endblock %}
{% block body %}
<div id="content-loop-container">
<div id="content-push-in"></div>
{% block sidebar %}
<aside class="sidebar bounceInLeft animated light" id="custom-sidebar-css">
<ul id="the_sidebar"></ul>
</aside>
{% endblock %}
</div>
<div id="more-button"></div>
{% endblock %}
{% block footer %} {% endblock %}
{% block javascripts %}
{% include 'assets/basescripts.html.twig' %}
{% endblock %}
</body>
</html>
This doesn't seem to work, it finds the template but prevents me from using the twig functions
$collection->add('home_route', new Route('/', array(
'_controller' => 'FrameworkBundle:Template:template',
'template' => '<path>/views/base.html.twig',
)));
My problem is next:
I have base.html.twig placed in view folder (root)
{# app/Resources/views/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>{% block title %}Test Application{% endblock %}</title>
</head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li>Home</li>
<li>Blog</li>
</ul>
{% endblock %}
</div>
<div id="content">
{% block body %}{% endblock %}
</div>
</body>
</html>
and index.html.twig in Blog directory (views/Blog):
{% extends '::base.html.twig' %}
{% block title %}
{{ parent() }}
{% endblock %}
{% block sidebar %}
{{ parent() }}
{% endblock %}
{% block body %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
My problem is next:
When I render and return that template it is shown just as index.html.twig and it doesn't use any part from the base template. Even I {{ parent() }} doesn't work (is not showing anything). Please help!
EDIT: it shows just articles part
Hah... I made it work... Simply changed ::base.html.twig with AcmeHelloBundle::base.html.twig ;)