first draft
This commit is contained in:
25
app/Resources/views/admin/blog/_form.html.twig
Normal file
25
app/Resources/views/admin/blog/_form.html.twig
Normal file
@@ -0,0 +1,25 @@
|
||||
{#
|
||||
By default, forms enable client-side validation. This means that you can't
|
||||
test the server-side validation errors from the browser. To temporarily
|
||||
disable this validation, add the 'novalidate' attribute:
|
||||
|
||||
{{ form_start(form, { attr: { novalidate: 'novalidate' } }) }}
|
||||
#}
|
||||
|
||||
{% if show_confirmation|default(false) %}
|
||||
{% set attr = {'data-confirmation': 'true'} %}
|
||||
{{ include('blog/_delete_post_confirmation.html.twig') }}
|
||||
{% endif %}
|
||||
|
||||
{{ form_start(form, { attr: attr|default({}) }) }}
|
||||
{{ form_widget(form) }}
|
||||
|
||||
<input type="submit" value="{{ button_label|default('label.create_post'|trans) }}"
|
||||
class="{{ button_css|default("btn btn-primary") }}" />
|
||||
|
||||
{% if include_back_to_home_link|default(false) %}
|
||||
<a href="{{ path('admin_post_index') }}" class="btn btn-link">
|
||||
{{ 'action.back_to_list'|trans }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{{ form_end(form) }}
|
||||
26
app/Resources/views/admin/blog/edit.html.twig
Normal file
26
app/Resources/views/admin/blog/edit.html.twig
Normal file
@@ -0,0 +1,26 @@
|
||||
{% extends 'admin/layout.html.twig' %}
|
||||
|
||||
{% block body_id 'admin_post_edit' %}
|
||||
|
||||
{% block main %}
|
||||
<h1>{{ 'title.edit_post'|trans({'%id%': post.id}) }}</h1>
|
||||
|
||||
{{ include('admin/blog/_form.html.twig', {
|
||||
form: edit_form,
|
||||
button_label: 'action.save'|trans,
|
||||
include_back_to_home_link: true,
|
||||
}, with_context = false) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
<div class="section actions">
|
||||
{{ include('admin/blog/_form.html.twig', {
|
||||
form: delete_form,
|
||||
button_label: 'action.delete_post'|trans,
|
||||
button_css: 'btn btn-lg btn-block btn-danger',
|
||||
show_confirmation: true,
|
||||
}, with_context = false) }}
|
||||
</div>
|
||||
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
57
app/Resources/views/admin/blog/index.html.twig
Normal file
57
app/Resources/views/admin/blog/index.html.twig
Normal file
@@ -0,0 +1,57 @@
|
||||
{% extends 'admin/layout.html.twig' %}
|
||||
|
||||
{% block body_id 'admin_post_index' %}
|
||||
|
||||
{% block main %}
|
||||
<h1>{{ 'title.post_list'|trans }}</h1>
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'label.title'|trans }}</th>
|
||||
<th><i class="fa fa-user"></i> {{ 'label.author'|trans }}</th>
|
||||
<th><i class="fa fa-calendar"></i> {{ 'label.published_at'|trans }}</th>
|
||||
<th><i class="fa fa-cogs"></i> {{ 'label.actions'|trans }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for post in posts %}
|
||||
<tr>
|
||||
<td>{{ post.title }}</td>
|
||||
<td>{{ post.authorEmail }}</td>
|
||||
{# it's not mandatory to set the timezone in localizeddate(). This is done to
|
||||
avoid errors when the 'intl' PHP extension is not available and the application
|
||||
is forced to use the limited "intl polyfill", which only supports UTC and GMT #}
|
||||
<td>{% if post.publishedAt %}{{ post.publishedAt|localizeddate('short', 'short', null, 'UTC') }}{% endif %}</td>
|
||||
<td>
|
||||
<div class="item-actions">
|
||||
<a href="{{ path('admin_post_show', { id: post.id }) }}" class="btn btn-sm btn-default">
|
||||
{{ 'action.show'|trans }}
|
||||
</a>
|
||||
|
||||
{% if post.isAuthor(app.user) %}
|
||||
<a href="{{ path('admin_post_edit', { id: post.id }) }}" class="btn btn-sm btn-primary">
|
||||
<i class="fa fa-edit"></i> {{ 'action.edit'|trans }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="4" align="center">{{ 'post.no_posts_found'|trans }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
<div class="section actions">
|
||||
<a href="{{ path('admin_post_new') }}" class="btn btn-lg btn-block btn-success">
|
||||
<i class="fa fa-plus"></i> {{ 'action.create_post'|trans }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
27
app/Resources/views/admin/blog/new.html.twig
Normal file
27
app/Resources/views/admin/blog/new.html.twig
Normal file
@@ -0,0 +1,27 @@
|
||||
{% extends 'admin/layout.html.twig' %}
|
||||
|
||||
{% block body_id 'admin_post_new' %}
|
||||
|
||||
{% block main %}
|
||||
<h1>{{ 'title.post_new'|trans }}</h1>
|
||||
|
||||
{{ form_start(form) }}
|
||||
{{ form_row(form.title) }}
|
||||
{{ form_row(form.summary) }}
|
||||
{{ form_row(form.content) }}
|
||||
{{ form_row(form.authorEmail) }}
|
||||
{{ form_row(form.publishedAt) }}
|
||||
|
||||
<input type="submit" value="{{ 'label.create_post'|trans }}" class="btn btn-primary" />
|
||||
|
||||
{{ form_widget(form.saveAndCreateNew, { label: 'label.save_and_create_new', attr: { class: 'btn btn-primary' } }) }}
|
||||
|
||||
<a href="{{ path('admin_post_index') }}" class="btn btn-link">
|
||||
{{ 'action.back_to_list'|trans }}
|
||||
</a>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
48
app/Resources/views/admin/blog/show.html.twig
Normal file
48
app/Resources/views/admin/blog/show.html.twig
Normal file
@@ -0,0 +1,48 @@
|
||||
{% extends 'admin/layout.html.twig' %}
|
||||
|
||||
{% block body_id 'admin_post_show' %}
|
||||
|
||||
{% block main %}
|
||||
<h1>{{ post.title }}</h1>
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>{{ 'label.summary'|trans }}</th>
|
||||
<td>{{ post.summary|md2html }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ 'label.content'|trans }}</th>
|
||||
<td>{{ post.content|md2html }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ 'label.author'|trans }}</th>
|
||||
<td><p>{{ post.authorEmail }}</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ 'label.published_at'|trans }}</th>
|
||||
{# it's not mandatory to set the timezone in localizeddate(). This is done to
|
||||
avoid errors when the 'intl' PHP extension is not available and the application
|
||||
is forced to use the limited "intl polyfill", which only supports UTC and GMT #}
|
||||
<td><p>{{ post.publishedAt|localizeddate('long', 'medium', null, 'UTC') }}</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
<div class="section">
|
||||
<a href="{{ path('admin_post_edit', { id: post.id }) }}" class="btn btn-lg btn-block btn-success">
|
||||
<i class="fa fa-edit"></i> {{ 'action.edit_contents'|trans }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
{{ include('admin/blog/_form.html.twig', {
|
||||
form: delete_form,
|
||||
button_label: 'action.delete_post'|trans,
|
||||
button_css: 'btn btn-lg btn-block btn-danger',
|
||||
show_confirmation: true,
|
||||
}, with_context = false) }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
9
app/Resources/views/admin/layout.html.twig
Normal file
9
app/Resources/views/admin/layout.html.twig
Normal file
@@ -0,0 +1,9 @@
|
||||
{#
|
||||
This is the base template of the all backend pages.
|
||||
See http://symfony.com/doc/current/book/templating.html#template-inheritance-and-layouts
|
||||
#}
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block header_navigation_links %}
|
||||
{{ knp_menu_render('admin', {'template': 'menu/admin_menu.html.twig'}) }}
|
||||
{% endblock %}
|
||||
122
app/Resources/views/base.html.twig
Normal file
122
app/Resources/views/base.html.twig
Normal file
@@ -0,0 +1,122 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>{% block title %}Symfony Demo application{% endblock %}</title>
|
||||
|
||||
{% block stylesheets %}
|
||||
{# uncomment the following lines to compile SCSS assets with Assetic
|
||||
|
||||
{% stylesheets filter="scssphp" output="css/app.css"
|
||||
"%kernel.root_dir%/Resources/assets/scss/bootstrap-flatly.scss"
|
||||
"%kernel.root_dir%/Resources/assets/scss/font-awesome.scss"
|
||||
"%kernel.root_dir%/Resources/assets/css/*.css"
|
||||
"%kernel.root_dir%/Resources/assets/scss/main.scss"
|
||||
%}
|
||||
<link rel="stylesheet" href="{{ asset_url }}" />
|
||||
{% endstylesheets %}
|
||||
#}
|
||||
|
||||
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
|
||||
{% endblock %}
|
||||
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
|
||||
</head>
|
||||
|
||||
<body id="{% block body_id %}{% endblock %}">
|
||||
|
||||
{% block header %}
|
||||
<header>
|
||||
<div class="navbar navbar-default navbar-static-top" role="navigation">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="{{ path('homepage') }}">
|
||||
Timesheet
|
||||
</a>
|
||||
|
||||
<button type="button" class="navbar-toggle"
|
||||
data-toggle="collapse"
|
||||
data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
|
||||
{% block header_navigation_links %}
|
||||
{{ knp_menu_render('main', {'template': 'menu/main_menu.html.twig'}) }}
|
||||
{% endblock %}
|
||||
|
||||
{#
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-globe"></i> <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu locales" role="menu">
|
||||
{% for locale in locales() %}
|
||||
<li {% if app.request.locale == locale.code %}class="active"{% endif %}><a href="{{ path(app.request.get('_route', 'blog_index'), app.request.get('_route_params', [])|merge({ _locale: locale.code })) }}">{{ locale.name|capitalize }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
#}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
{% endblock %}
|
||||
|
||||
<div class="container body-container">
|
||||
{% block body %}
|
||||
<div class="row">
|
||||
<div id="main" class="col-sm-12">
|
||||
{{ include('default/_flash_messages.html.twig') }}
|
||||
|
||||
{% block main %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
{% block footer %}
|
||||
<footer>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div id="footer-copyright" class="col-md-6">
|
||||
<p>© {{ 'now'|date('Y') }} - The Symfony Project</p>
|
||||
<p>{{ 'mit_license'|trans }}</p>
|
||||
</div>
|
||||
<div id="footer-resources" class="col-md-6">
|
||||
<p>
|
||||
<a href="https://twitter.com/symfony"><i class="fa fa-twitter"></i></a>
|
||||
<a href="https://www.facebook.com/SensioLabs"><i class="fa fa-facebook"></i></a>
|
||||
<a href="https://symfony.com/blog/"><i class="fa fa-rss"></i></a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
{% endblock %}
|
||||
|
||||
{% block javascripts %}
|
||||
{# uncomment the following lines to combine and minimize JavaScript assets with Assetic
|
||||
{% javascripts filter="?jsqueeze" output="js/app.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/jquery-2.1.4.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/moment.min.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/bootstrap-3.3.4.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/highlight.pack.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/bootstrap-datetimepicker.min.js"
|
||||
"%kernel.root_dir%/Resources/assets/js/main.js" %}
|
||||
<script src="{{ asset_url }}"></script>
|
||||
{% endjavascripts %}
|
||||
#}
|
||||
|
||||
<script src="{{ asset('js/app.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{# it's not mandatory to set the timezone in localizeddate(). This is done to
|
||||
avoid errors when the 'intl' PHP extension is not available and the application
|
||||
is forced to use the limited "intl polyfill", which only supports UTC and GMT #}
|
||||
<!-- Page rendered on {{ 'now'|localizeddate('long', 'long', null, 'UTC') }} -->
|
||||
</body>
|
||||
</html>
|
||||
35
app/Resources/views/blog/_comment_form.html.twig
Normal file
35
app/Resources/views/blog/_comment_form.html.twig
Normal file
@@ -0,0 +1,35 @@
|
||||
{#
|
||||
By default, forms enable client-side validation. This means that you can't
|
||||
test the server-side validation errors from the browser. To temporarily
|
||||
disable this validation, add the 'novalidate' attribute:
|
||||
|
||||
{{ form_start(form, { method: ..., action: ..., attr: { novalidate: 'novalidate' } }) }}
|
||||
#}
|
||||
|
||||
{{ form_start(form, { method: 'POST', action: path('comment_new', { 'postSlug': post.slug }) }) }}
|
||||
{# instead of displaying form fields one by one, you can also display them
|
||||
all with their default options and styles just by calling to this function:
|
||||
|
||||
{{ form_widget(form) }}
|
||||
#}
|
||||
|
||||
<fieldset>
|
||||
<legend>{{ 'title.add_comment'|trans }}</legend>
|
||||
|
||||
{# Render any global form error (e.g. when a constraint on a public getter method failed) #}
|
||||
{{ form_errors(form) }}
|
||||
|
||||
<div class="form-group {% if not form.content.vars.valid %}has-error{% endif %}">
|
||||
{{ form_label(form.content, 'label.content', { label_attr: { class: 'hidden' }}) }}
|
||||
|
||||
{# Render any errors for the "content" field (e.g. when a class property constraint failed) #}
|
||||
{{ form_errors(form.content) }}
|
||||
|
||||
{{ form_widget(form.content, { attr: { rows: 10 } }) }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<button class="btn btn-primary pull-right" type="submit">{{ 'action.publish_comment'|trans }}</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
{{ form_end(form) }}
|
||||
19
app/Resources/views/blog/_delete_post_confirmation.html.twig
Normal file
19
app/Resources/views/blog/_delete_post_confirmation.html.twig
Normal file
@@ -0,0 +1,19 @@
|
||||
{# Bootstrap modal, see http://getbootstrap.com/javascript/#modals #}
|
||||
<div class="modal fade" id="confirmationModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body">
|
||||
<h4>{{ 'delete_post_modal.title'|trans }}</h4>
|
||||
<p>{{ 'delete_post_modal.body'|trans }}</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" id="btnNo" data-dismiss="modal">
|
||||
{{ 'label.cancel'|trans }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-danger" id="btnYes" data-dismiss="modal">
|
||||
{{ 'label.delete_post'|trans }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
15
app/Resources/views/blog/about.html.twig
Normal file
15
app/Resources/views/blog/about.html.twig
Normal file
@@ -0,0 +1,15 @@
|
||||
<div class="section about">
|
||||
<div class="well well-lg">
|
||||
<p>
|
||||
{{ 'help.app_description'|trans|raw }}
|
||||
</p>
|
||||
<p>
|
||||
{{ 'help.more_information'|trans|raw }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# it's not mandatory to set the timezone in localizeddate(). This is done to
|
||||
avoid errors when the 'intl' PHP extension is not available and the application
|
||||
is forced to use the limited "intl polyfill", which only supports UTC and GMT #}
|
||||
<!-- Fragment rendered on {{ 'now'|localizeddate('long', 'long', null, 'UTC') }} -->
|
||||
11
app/Resources/views/blog/comment_form_error.html.twig
Normal file
11
app/Resources/views/blog/comment_form_error.html.twig
Normal file
@@ -0,0 +1,11 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body_id 'comment_form_error' %}
|
||||
|
||||
{% block main %}
|
||||
<h1 class="text-danger">{{ 'title.comment_error'|trans }}</h1>
|
||||
|
||||
<div class="well">
|
||||
{{ include('blog/_comment_form.html.twig') }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
27
app/Resources/views/blog/index.html.twig
Normal file
27
app/Resources/views/blog/index.html.twig
Normal file
@@ -0,0 +1,27 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body_id 'blog_index' %}
|
||||
|
||||
{% block main %}
|
||||
{% for post in posts %}
|
||||
<article class="post">
|
||||
<h2>
|
||||
<a href="{{ path('blog_post', { slug: post.slug }) }}">
|
||||
{{ post.title }}
|
||||
</a>
|
||||
</h2>
|
||||
|
||||
{{ post.summary|md2html }}
|
||||
</article>
|
||||
{% else %}
|
||||
<div class="well">{{ 'post.no_posts_found'|trans }}</div>
|
||||
{% endfor %}
|
||||
|
||||
<div class="navigation text-center">
|
||||
{{ pagerfanta(posts, 'twitter_bootstrap3_translated', { routeName: 'blog_index_paginated' }) }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
64
app/Resources/views/blog/post_show.html.twig
Normal file
64
app/Resources/views/blog/post_show.html.twig
Normal file
@@ -0,0 +1,64 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body_id 'blog_post_show' %}
|
||||
|
||||
{% block main %}
|
||||
<h1>{{ post.title }}</h1>
|
||||
|
||||
{{ post.content|md2html }}
|
||||
|
||||
<div id="post-add-comment" class="well">
|
||||
{# The 'IS_AUTHENTICATED_FULLY' role ensures that the user has entered
|
||||
his/her credentials (login + password) during this session. If he/she
|
||||
is automatically logged via the 'Remember Me' functionality, he/she won't
|
||||
be able to add a comment.
|
||||
See http://symfony.com/doc/current/cookbook/security/remember_me.html#forcing-the-user-to-re-authenticate-before-accessing-certain-resources
|
||||
#}
|
||||
{% if is_granted('IS_AUTHENTICATED_FULLY') %}
|
||||
{{ render(controller('AppBundle:Blog:commentForm', { 'id': post.id })) }}
|
||||
{% else %}
|
||||
<p>
|
||||
<a class="btn btn-success" href="{{ path('security_login') }}">
|
||||
<i class="fa fa-sign-in"></i> {{ 'action.sign_in'|trans }}
|
||||
</a>
|
||||
{{ 'post.to_publish_a_comment'|trans }}
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<h3>{{ 'post.num_comments'|transchoice(post.comments|length) }}</h3>
|
||||
|
||||
{% for comment in post.comments %}
|
||||
<div class="row post-comment">
|
||||
<h4 class="col-sm-3">
|
||||
<strong>{{ comment.authorEmail }}</strong> {{ 'post.commented_on'|trans }}
|
||||
{# it's not mandatory to set the timezone in localizeddate(). This is done to
|
||||
avoid errors when the 'intl' PHP extension is not available and the application
|
||||
is forced to use the limited "intl polyfill", which only supports UTC and GMT #}
|
||||
<strong>{{ comment.publishedAt|localizeddate('medium', 'short', null, 'UTC') }}</strong>
|
||||
</h4>
|
||||
<div class="col-sm-9">
|
||||
{{ comment.content|md2html }}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="post-comment">
|
||||
<p>{{ 'post.no_comments'|trans }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{% if app.user and post.isAuthor(app.user) %}
|
||||
<div class="section">
|
||||
<a class="btn btn-lg btn-block btn-success" href="{{ path('admin_post_edit', { id: post.id }) }}">
|
||||
<i class="fa fa-edit"></i> {{ 'action.edit_post'|trans }}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# the parent() function includes the contents defined by the parent template
|
||||
('base.html.twig') for this block ('sidebar'). This is a very convenient way
|
||||
to share common contents in different templates #}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
25
app/Resources/views/default/_flash_messages.html.twig
Normal file
25
app/Resources/views/default/_flash_messages.html.twig
Normal file
@@ -0,0 +1,25 @@
|
||||
{#
|
||||
This is a template fragment designed to be included in other templates
|
||||
See http://symfony.com/doc/current/book/templating.html#including-other-templates
|
||||
|
||||
A common practice to better distinguish between templates and fragments is to
|
||||
prefix fragments with an underscore. That's why this template is called
|
||||
'_flash_messages.html.twig' instead of 'flash_messages.html.twig'
|
||||
#}
|
||||
|
||||
{% if app.session.started and app.session.flashBag.peekAll is not empty %}
|
||||
<div class="messages">
|
||||
{% for type, messages in app.session.flashBag.all %}
|
||||
{% for message in messages %}
|
||||
{# Bootstrap alert, see http://getbootstrap.com/components/#alerts #}
|
||||
<div class="alert alert-dismissible alert-{{ type }}" role="alert">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
|
||||
{{ message|trans }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
19
app/Resources/views/form/fields.html.twig
Normal file
19
app/Resources/views/form/fields.html.twig
Normal file
@@ -0,0 +1,19 @@
|
||||
{#
|
||||
Each field type is rendered by a template fragment, which is determined
|
||||
by the name of your form type class (DateTimePickerType -> date_time_picker)
|
||||
and the suffix "_widget". This can be controlled by overriding getBlockPrefix()
|
||||
in DateTimePickerType.
|
||||
|
||||
See http://symfony.com/doc/current/cookbook/form/create_custom_field_type.html#creating-a-template-for-the-field
|
||||
#}
|
||||
|
||||
{% block date_time_picker_widget %}
|
||||
{% spaceless %}
|
||||
<div class="input-group date" data-toggle="datetimepicker">
|
||||
{{ block('datetime_widget') }}
|
||||
<span class="input-group-addon">
|
||||
<span class="fa fa-calendar"></span>
|
||||
</span>
|
||||
</div>
|
||||
{% endspaceless %}
|
||||
{% endblock %}
|
||||
1
app/Resources/views/menu/admin_menu.html.twig
Normal file
1
app/Resources/views/menu/admin_menu.html.twig
Normal file
@@ -0,0 +1 @@
|
||||
{% extends 'menu/main_menu.html.twig' %}
|
||||
18
app/Resources/views/menu/main_menu.html.twig
Normal file
18
app/Resources/views/menu/main_menu.html.twig
Normal file
@@ -0,0 +1,18 @@
|
||||
{% extends 'knp_menu.html.twig' %}
|
||||
|
||||
{% block linkElement %}
|
||||
<a href="{{ item.uri }}"{{ knp_menu.attributes(item.linkAttributes) }}>
|
||||
{% if item.childrenAttributes.icon is defined %}
|
||||
<i class="fa fa-{{ item.childrenAttributes.icon }} }}"></i>
|
||||
{% endif %}
|
||||
{{ block('label') }}
|
||||
</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block label %}
|
||||
{% if options.allow_safe_labels and item.getExtra('safe_label', false) %}
|
||||
{{ item.label|raw }}
|
||||
{% else %}
|
||||
{{ item.label|trans }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
54
app/Resources/views/security/login.html.twig
Normal file
54
app/Resources/views/security/login.html.twig
Normal file
@@ -0,0 +1,54 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body_id 'login' %}
|
||||
|
||||
{% block main %}
|
||||
{% if error %}
|
||||
<div class="alert alert-danger">
|
||||
{{ error.messageKey|trans(error.messageData, 'security') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-4"></div>
|
||||
<div class="col-sm-4">
|
||||
<div class="well">
|
||||
<form action="{{ path('security_login') }}" method="post">
|
||||
<fieldset>
|
||||
<legend><i class="fa fa-lock"></i> {{ 'title.login'|trans }}</legend>
|
||||
<div class="form-group">
|
||||
<label for="username">{{ 'label.username'|trans }}</label>
|
||||
<input type="text" id="username" name="_username" value="{{ last_username }}" class="form-control"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">{{ 'label.password'|trans }}</label>
|
||||
<input type="password" id="password" name="_password" class="form-control" />
|
||||
</div>
|
||||
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}"/>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fa fa-sign-in"></i> {{ 'action.sign_in'|trans }}
|
||||
</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block javascripts %}
|
||||
{{ parent() }}
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var usernameEl = $('#username');
|
||||
var passwordEl = $('#password');
|
||||
// in a real application, hardcoding the user/password would be idiotic
|
||||
// but for the demo application it's very convenient to do so
|
||||
if (!usernameEl.val() && !passwordEl.val()) {
|
||||
usernameEl.val('anna_admin');
|
||||
passwordEl.val('kitten');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user