install symfony demo with installer

This commit is contained in:
2021-04-16 09:37:45 +02:00
parent 72fd1cf02d
commit 3751003188
191 changed files with 32965 additions and 1 deletions

View File

@@ -0,0 +1,8 @@
{{ include('blog/_delete_post_confirmation.html.twig') }}
<form action="{{ url('admin_post_delete', {id: post.id}) }}" method="post" data-confirmation="true" id="delete-form">
<input type="hidden" name="token" value="{{ csrf_token('delete') }}" />
<button type="submit" class="btn btn-lg btn-block btn-danger">
<i class="fa fa-trash" aria-hidden="true"></i>
{{ 'action.delete_post'|trans }}
</button>
</form>

View File

@@ -0,0 +1,26 @@
{#
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) }}
<button type="submit" class="{{ button_css|default("btn btn-primary") }}">
<i class="fa fa-save" aria-hidden="true"></i> {{ button_label|default('label.create_post'|trans) }}
</button>
{% if include_back_to_home_link|default(false) %}
<a href="{{ path('admin_post_index') }}" class="btn btn-link">
<i class="fa fa-list-alt" aria-hidden="true"></i> {{ 'action.back_to_list'|trans }}
</a>
{% endif %}
{{ form_end(form) }}

View File

@@ -0,0 +1,29 @@
{% 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: form,
button_label: 'action.save'|trans,
include_back_to_home_link: true,
}, with_context = false) }}
{% endblock %}
{% block sidebar %}
<div class="section">
<a href="{{ path('admin_post_show', {id: post.id}) }}" class="btn btn-lg btn-block btn-success">
<i class="fa fa-eye" aria-hidden="true"></i> {{ 'action.show_post'|trans }}
</a>
</div>
<div class="section actions">
{{ include('admin/blog/_delete_form.html.twig', {post: post}, with_context = false) }}
</div>
{{ parent() }}
{{ show_source_code(_self) }}
{% endblock %}

View File

@@ -0,0 +1,55 @@
{% extends 'admin/layout.html.twig' %}
{% block body_id 'admin_post_index' %}
{% block main %}
<h1>{{ 'title.post_list'|trans }}</h1>
<table class="table table-striped table-middle-aligned">
<thead>
<tr>
<th scope="col">{{ 'label.title'|trans }}</th>
<th scope="col"><i class="fa fa-calendar" aria-hidden="true"></i> {{ 'label.published_at'|trans }}</th>
<th scope="col" class="text-center"><i class="fa fa-cogs" aria-hidden="true"></i> {{ 'label.actions'|trans }}</th>
</tr>
</thead>
<tbody>
{% for post in posts %}
<tr>
<td>{{ post.title }}</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>{{ post.publishedAt|format_datetime('medium', 'short', '', 'UTC') }}</td>
<td class="text-right">
<div class="item-actions">
<a href="{{ path('admin_post_show', {id: post.id}) }}" class="btn btn-sm btn-default">
<i class="fa fa-eye" aria-hidden="true"></i> {{ 'action.show'|trans }}
</a>
<a href="{{ path('admin_post_edit', {id: post.id}) }}" class="btn btn-sm btn-primary">
<i class="fa fa-edit" aria-hidden="true"></i> {{ 'action.edit'|trans }}
</a>
</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" aria-hidden="true"></i> {{ 'action.create_post'|trans }}
</a>
</div>
{{ parent() }}
{{ show_source_code(_self) }}
{% endblock %}

View File

@@ -0,0 +1,29 @@
{% 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.publishedAt) }}
{{ form_row(form.tags) }}
<button type="submit" class="btn btn-primary">
<i class="fa fa-save" aria-hidden="true"></i> {{ 'label.create_post'|trans }}
</button>
{{ 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">
<i class="fa fa-list-alt" aria-hidden="true"></i> {{ 'action.back_to_list'|trans }}
</a>
{{ form_end(form) }}
{% endblock %}
{% block sidebar %}
{{ parent() }}
{{ show_source_code(_self) }}
{% endblock %}

View File

@@ -0,0 +1,36 @@
{% extends 'admin/layout.html.twig' %}
{% block body_id 'admin_post_show' %}
{% block main %}
<h1>{{ post.title }}</h1>
<p class="post-metadata">
<span class="metadata"><i class="fa fa-calendar"></i> {{ post.publishedAt|format_datetime('long', 'medium', '', 'UTC') }}</span>
<span class="metadata"><i class="fa fa-user"></i> {{ post.author.fullName }}</span>
</p>
<div class="well">
<p class="m-b-0"><strong>{{ 'label.summary'|trans }}</strong>: {{ post.summary }}</p>
</div>
{{ post.content|markdown_to_html|sanitize_html }}
{{ include('blog/_post_tags.html.twig') }}
{% 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" aria-hidden="true"></i> {{ 'action.edit_contents'|trans }}
</a>
</div>
<div class="section">
{{ include('admin/blog/_delete_form.html.twig', {post: post}, with_context = false) }}
</div>
{{ parent() }}
{{ show_source_code(_self) }}
{% endblock %}

View File

@@ -0,0 +1,31 @@
{#
This is the base template of the all backend pages. Since this layout is similar
to the global layout, we inherit from it to just change the contents of some
blocks. In practice, backend templates are using a three-level inheritance,
showing how powerful, yet easy to use, is Twig's inheritance mechanism.
See https://symfony.com/doc/current/templates.html#template-inheritance-and-layouts
#}
{% extends 'base.html.twig' %}
{% block stylesheets %}
{{ parent() }}
{{ encore_entry_link_tags('admin') }}
{% endblock %}
{% block header_navigation_links %}
<li>
<a href="{{ path('admin_post_index') }}">
<i class="fa fa-list-alt" aria-hidden="true"></i> {{ 'menu.post_list'|trans }}
</a>
</li>
<li>
<a href="{{ path('blog_index') }}">
<i class="fa fa-home" aria-hidden="true"></i> {{ 'menu.back_to_blog'|trans }}
</a>
</li>
{% endblock %}
{% block javascripts %}
{{ parent() }}
{{ encore_entry_script_tags('admin') }}
{% endblock %}

View File

@@ -0,0 +1,162 @@
{#
This is the base template used as the application layout which contains the
common elements and decorates all the other templates.
See https://symfony.com/doc/current/templates.html#template-inheritance-and-layouts
#}
<!DOCTYPE html>
<html lang="{{ app.request.locale }}">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>{% block title %}Symfony Demo application{% endblock %}</title>
<link rel="alternate" type="application/rss+xml" title="{{ 'rss.title'|trans }}" href="{{ path('blog_rss') }}">
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{% 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 col-md-3 col-lg-2">
<a class="navbar-brand" href="{{ path('homepage') }}">
Symfony Demo
</a>
<button type="button" class="navbar-toggle"
data-toggle="collapse"
data-target=".navbar-collapse">
<span class="sr-only">{{ 'menu.toggle_nav'|trans }}</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
{% block header_navigation_links %}
<li>
<a href="{{ path('blog_index') }}">
<i class="fa fa-home" aria-hidden="true"></i> {{ 'menu.homepage'|trans }}
</a>
</li>
{% if is_granted('ROLE_ADMIN') %}
<li>
<a href="{{ path('admin_post_index') }}">
<i class="fa fa-lock" aria-hidden="true"></i> {{ 'menu.admin'|trans }}
</a>
</li>
{% endif %}
{% endblock %}
<li>
<a href="{{ path('blog_search') }}"> <i class="fa fa-search"></i> {{ 'menu.search'|trans }}</a>
</li>
{% if app.user %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false" id="user">
<i class="fa fa-user" aria-hidden="true"></i>
<span class="caret"></span>
<span class="sr-only">{{ app.user.fullname }}</span>
</a>
<ul class="dropdown-menu user" role="menu" aria-labelledby="user">
<li>
<a href="{{ path('user_edit') }}">
<i class="fa fa-edit" aria-hidden="true"></i> {{ 'menu.user'|trans }}
</a>
</li>
<li class="divider"></li>
<li>
<a href="{{ path('security_logout') }}">
<i class="fa fa-sign-out" aria-hidden="true"></i> {{ 'menu.logout'|trans }}
</a>
</li>
</ul>
</li>
{% endif %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false" id="locales">
<i class="fa fa-globe" aria-hidden="true"></i>
<span class="caret"></span>
<span class="sr-only">{{ 'menu.choose_language'|trans }}</span>
</a>
<ul class="dropdown-menu locales" role="menu" aria-labelledby="locales">
{% for locale in locales() %}
<li {% if app.request.locale == locale.code %}aria-checked="true" class="active"{% else %}aria-checked="false"{% endif %} role="menuitem"><a href="{{ path(app.request.get('_route', 'blog_index'), app.request.get('_route_params', [])|merge({_locale: locale.code})) }}">{{ locale.name|capitalize }} <small>{{ locale.code[0:2] }}</small></a></li>
{% endfor %}
</ul>
</li>
</ul>
</div>
</div>
</div>
</header>
{% endblock %}
<div class="container body-container">
{% block body %}
<div class="row">
<div id="main" class="col-sm-9">
{{ include('default/_flash_messages.html.twig') }}
{% block main %}{% endblock %}
</div>
<div id="sidebar" class="col-sm-3">
{% block sidebar %}
{{ render_esi(controller('Symfony\\Bundle\\FrameworkBundle\\Controller\\TemplateController::templateAction', {
'template': 'blog/about.html.twig',
'sharedAge': 600,
'_locale': app.request.locale
})) }}
{% endblock %}
</div>
</div>
{% endblock %}
</div>
{% block footer %}
<footer>
<div class="container">
<div class="row">
<div id="footer-copyright" class="col-md-6">
<p>&copy; {{ '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" title="Symfony Twitter">
<i class="fa fa-twitter" aria-hidden="true"></i>
</a>
<a href="https://www.facebook.com/SensioLabs" title="SensioLabs Facebook">
<i class="fa fa-facebook" aria-hidden="true"></i>
</a>
<a href="https://symfony.com/blog/" title="Symfony Blog">
<i class="fa fa-rss" aria-hidden="true"></i>
</a>
</p>
</div>
</div>
</div>
</footer>
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% 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'|format_datetime('long', 'long', '', 'UTC') }} -->
</body>
</html>

View File

@@ -0,0 +1,40 @@
{#
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>
<i class="fa fa-comment" aria-hidden="true"></i> {{ '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: 'sr-only'}}) }}
{# 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}}) }}
{{ form_help(form.content) }}
</div>
<div class="form-group">
<button class="btn btn-primary pull-right" type="submit">
<i class="fa fa-paper-plane" aria-hidden="true"></i> {{ 'action.publish_comment'|trans }}
</button>
</div>
</fieldset>
{{ form_end(form) }}

View File

@@ -0,0 +1,19 @@
{# Bootstrap modal, see https://getbootstrap.com/docs/3.4/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">
<i class="fa fa-ban" aria-hidden="true"></i> {{ 'label.cancel'|trans }}
</button>
<button type="button" class="btn btn-danger" id="btnYes" data-dismiss="modal">
<i class="fa fa-trash" aria-hidden="true"></i> {{ 'label.delete_post'|trans }}
</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
{% if not post.tags.empty %}
<p class="post-tags">
{% for tag in post.tags %}
<a href="{{ path('blog_index', {'tag': tag.name == app.request.query.get('tag') ? null : tag.name}) }}"
class="label label-{{ tag.name == app.request.query.get('tag') ? 'success' : 'default' }}"
>
<i class="fa fa-tag"></i> {{ tag.name }}
</a>
{% endfor %}
</p>
{% endif %}

View File

@@ -0,0 +1,5 @@
<div class="section rss">
<a href="{{ path('blog_rss', app.request.query.all) }}">
<i class="fa fa-rss" aria-hidden="true"></i> {{ 'menu.rss'|trans }}
</a>
</div>

View 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'|format_datetime('long', 'long', '', 'UTC') }} -->

View 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 %}

View File

@@ -0,0 +1,59 @@
{% extends 'base.html.twig' %}
{% block body_id 'blog_index' %}
{% block main %}
{% for post in paginator.results %}
<article class="post">
<h2>
<a href="{{ path('blog_post', {slug: post.slug}) }}">
{{ post.title }}
</a>
</h2>
<p class="post-metadata">
<span class="metadata"><i class="fa fa-calendar"></i> {{ post.publishedAt|format_datetime('long', 'medium', '', 'UTC') }}</span>
<span class="metadata"><i class="fa fa-user"></i> {{ post.author.fullName }}</span>
</p>
<p>{{ post.summary }}</p>
{{ include('blog/_post_tags.html.twig') }}
</article>
{% else %}
<div class="well">{{ 'post.no_posts_found'|trans }}</div>
{% endfor %}
{% if paginator.hasToPaginate %}
<div class="navigation text-center">
<ul class="pagination">
{% if paginator.hasPreviousPage %}
<li class="prev"><a href="{{ path('blog_index_paginated', {page: paginator.previousPage, tag: tagName}) }}" rel="previous"><i class="fa fw fa-long-arrow-left"></i> {{ 'paginator.previous'|trans }}</a></li>
{% else %}
<li class="prev disabled"><span><i class="fa fw fa-arrow-left"></i> {{ 'paginator.previous'|trans }}</span></li>
{% endif %}
{% for i in 1..paginator.lastPage %}
{% if i == paginator.currentPage %}
<li class="active"><span>{{ i }} <span class="sr-only">{{ 'paginator.current'|trans }}</span></span></li>
{% else %}
<li><a href="{{ path('blog_index_paginated', {page: i, tag: tagName}) }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if paginator.hasNextPage %}
<li class="next"><a href="{{ path('blog_index_paginated', {page: paginator.nextPage, tag: tagName}) }}" rel="next">{{ 'paginator.next'|trans }} <i class="fa fw fa-arrow-right"></i></a></li>
{% else %}
<li class="next disabled"><span>{{ 'paginator.next'|trans }} <i class="fa fw fa-arrow-right"></i></span></li>
{% endif %}
</ul>
</div>
{% endif %}
{% endblock %}
{% block sidebar %}
{{ parent() }}
{{ show_source_code(_self) }}
{{ include('blog/_rss.html.twig') }}
{% endblock %}

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>{{ 'rss.title'|trans }}</title>
<description>{{ 'rss.description'|trans }}</description>
<pubDate>{{ 'now'|date('r', timezone='GMT') }}</pubDate>
<lastBuildDate>{{ (paginator.results|last).publishedAt|default('now')|date('r', timezone='GMT') }}</lastBuildDate>
<link>{{ url('blog_index') }}</link>
<language>{{ app.request.locale }}</language>
{% for post in paginator.results %}
<item>
<title>{{ post.title }}</title>
<description>{{ post.summary }}</description>
<link>{{ url('blog_post', {'slug': post.slug}) }}</link>
<guid>{{ url('blog_post', {'slug': post.slug}) }}</guid>
<pubDate>{{ post.publishedAt|date(format='r', timezone='GMT') }}</pubDate>
<author>{{ post.author.email }}</author>
{% for tag in post.tags %}
<category>{{ tag.name }}</category>
{% endfor %}
</item>
{% endfor %}
</channel>
</rss>

View File

@@ -0,0 +1,77 @@
{% extends 'base.html.twig' %}
{% block body_id 'blog_post_show' %}
{% block main %}
<h1>{{ post.title }}</h1>
<p class="post-metadata">
<span class="metadata"><i class="fa fa-calendar"></i> {{ post.publishedAt|format_datetime('long', 'medium', '', 'UTC') }}</span>
<span class="metadata"><i class="fa fa-user"></i> {{ post.author.fullName }}</span>
</p>
{{ post.content|markdown_to_html|sanitize_html }}
{{ include('blog/_post_tags.html.twig') }}
<div id="post-add-comment" class="well">
{# The 'IS_AUTHENTICATED_FULLY' role ensures that the user has entered
their credentials (login + password) during this session. If they
are automatically logged via the 'Remember Me' functionality, they won't
be able to add a comment.
See https://symfony.com/doc/current/security/remember_me.html#forcing-the-user-to-re-authenticate-before-accessing-certain-resources
#}
{% if is_granted('IS_AUTHENTICATED_FULLY') %}
{{ render(controller('App\\Controller\\BlogController::commentForm', {'id': post.id})) }}
{% else %}
<p>
<a class="btn btn-success" href="{{ path('security_login', {'redirect_to': app.request.pathInfo}) }}">
<i class="fa fa-sign-in" aria-hidden="true"></i> {{ 'action.sign_in'|trans }}
</a>
{{ 'post.to_publish_a_comment'|trans }}
</p>
{% endif %}
</div>
<h3>
<i class="fa fa-comments" aria-hidden="true"></i> {{ 'post.num_comments'|trans({ 'count': post.comments|length }) }}
</h3>
{% for comment in post.comments %}
<div class="row post-comment">
<a name="comment_{{ comment.id }}"></a>
<h4 class="col-sm-3">
<strong>{{ comment.author.fullName }}</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|format_datetime('medium', 'short', '', 'UTC') }}</strong>
</h4>
<div class="col-sm-9">
{{ comment.content|markdown_to_html|sanitize_html }}
</div>
</div>
{% else %}
<div class="post-comment">
<p>{{ 'post.no_comments'|trans }}</p>
</div>
{% endfor %}
{% endblock %}
{% block sidebar %}
{% if is_granted('edit', post) %}
<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" aria-hidden="true"></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() }}
{{ show_source_code(_self) }}
{{ include('blog/_rss.html.twig') }}
{% endblock %}

View File

@@ -0,0 +1,32 @@
{% extends 'base.html.twig' %}
{% block javascripts %}
{{ parent() }}
{{ encore_entry_script_tags('search') }}
{% endblock %}
{% block body_id 'blog_search' %}
{% block main %}
<form action="{{ path('blog_search') }}" method="get">
<div class="form-group">
<input name="q"
class="form-control search-field"
placeholder="{{ 'post.search_for'|trans }}"
autocomplete="off"
value="{{ query }}"
autofocus
data-no-results-message="{{ 'post.search_no_results'|trans }}"
>
</div>
</form>
<div id="results">
</div>
{% endblock %}
{% block sidebar %}
{{ parent() }}
{{ show_source_code(_self) }}
{% endblock %}

View File

@@ -0,0 +1,30 @@
{#
This template is used to render any error different from 403, 404 and 500.
This is the simplest way to customize error pages in Symfony applications.
In case you need it, you can also hook into the internal exception handling
made by Symfony. This allows you to perform advanced tasks and even recover
your application from some errors.
See https://symfony.com/doc/current/controller/error_pages.html
#}
{% extends 'base.html.twig' %}
{% block body_id 'error' %}
{% block main %}
<h1 class="text-danger">{{ 'http_error.name'|trans({ '%status_code%': status_code }) }}</h1>
<p class="lead">
{{ 'http_error.description'|trans({ '%status_code%': status_code }) }}
</p>
<p>
{{ 'http_error.suggestion'|trans({ '%url%': path('blog_index') })|raw }}
</p>
{% endblock %}
{% block sidebar %}
{{ parent() }}
{{ show_source_code(_self) }}
{% endblock %}

View File

@@ -0,0 +1,30 @@
{#
This template is used to render errors of type HTTP 403 (Forbidden)
This is the simplest way to customize error pages in Symfony applications.
In case you need it, you can also hook into the internal exception handling
made by Symfony. This allows you to perform advanced tasks and even recover
your application from some errors.
See https://symfony.com/doc/current/controller/error_pages.html
#}
{% extends 'base.html.twig' %}
{% block body_id 'error' %}
{% block main %}
<h1 class="text-danger"><i class="fa fa-unlock-alt" aria-hidden="true"></i> {{ 'http_error.name'|trans({ '%status_code%': 403 }) }}</h1>
<p class="lead">
{{ 'http_error_403.description'|trans }}
</p>
<p>
{{ 'http_error_403.suggestion'|trans }}
</p>
{% endblock %}
{% block sidebar %}
{{ parent() }}
{{ show_source_code(_self) }}
{% endblock %}

View File

@@ -0,0 +1,30 @@
{#
This template is used to render errors of type HTTP 404 (Not Found)
This is the simplest way to customize error pages in Symfony applications.
In case you need it, you can also hook into the internal exception handling
made by Symfony. This allows you to perform advanced tasks and even recover
your application from some errors.
See https://symfony.com/doc/current/controller/error_pages.html
#}
{% extends 'base.html.twig' %}
{% block body_id 'error' %}
{% block main %}
<h1 class="text-danger">{{ 'http_error.name'|trans({ '%status_code%': 404 }) }}</h1>
<p class="lead">
{{ 'http_error_404.description'|trans }}
</p>
<p>
{{ 'http_error_404.suggestion'|trans({ '%url%': path('blog_index') })|raw }}
</p>
{% endblock %}
{% block sidebar %}
{{ parent() }}
{{ show_source_code(_self) }}
{% endblock %}

View File

@@ -0,0 +1,35 @@
{#
This template is used to render errors of type HTTP 500 (Internal Server Error)
This is the simplest way to customize error pages in Symfony applications.
In case you need it, you can also hook into the internal exception handling
made by Symfony. This allows you to perform advanced tasks and even recover
your application from some errors.
See https://symfony.com/doc/current/controller/error_pages.html
#}
{% extends 'base.html.twig' %}
{% block stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="/build/css/app.4aa95248.css">
{% endblock %}
{% block body_id 'error' %}
{% block main %}
<h1 class="text-danger">{{ 'http_error.name'|trans({ '%status_code%': 500 }) }}</h1>
<p class="lead">
{{ 'http_error_500.description'|trans }}
</p>
<p>
{{ 'http_error_500.suggestion'|trans({ '%url%': path('blog_index') })|raw }}
</p>
{% endblock %}
{% block sidebar %}
{{ parent() }}
{{ show_source_code(_self) }}
{% endblock %}

View File

@@ -0,0 +1,35 @@
<div class="section source-code">
<p>
{{ 'help.show_code'|trans|raw }}
</p>
<button type="button" class="btn btn-default btn-lg btn-block" data-toggle="modal" data-target="#sourceCodeModal">
<i class="fa fa-cogs" aria-hidden="true"></i> {{ 'action.show_code'|trans }}
</button>
<div class="modal fade" id="sourceCodeModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="{{ 'action.close'|trans }}">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title"><i class="fa fa-code" aria-hidden="true"></i> {{ 'title.source_code'|trans }}</h4>
</div>
<div class="modal-body">
{% if controller %}
<h3><a href="https://symfony.com/doc/current/controller.html" target="_blank">{{ 'title.controller_code'|trans }}</a><small class="pull-right">{{ controller.file_path|format_file(controller.starting_line) }}</small></h3>
<pre><code class="php">{{ controller.source_code }}</code></pre>
{% else %}
<h3><a href="https://symfony.com/doc/current/controller.html">{{ 'title.controller_code'|trans }}</a></h3>
<pre><code>{{ 'not_available'|trans }}</code></pre>
{% endif %}
<h3><a href="https://symfony.com/doc/current/templates.html" target="_blank">{{ 'title.twig_template_code'|trans }}</a><small class="pull-right">{{ template.file_path|format_file(template.starting_line) }}</small></h3>
<pre><code class="twig">{{ template.source_code }}</code></pre>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,32 @@
{#
This is a template fragment designed to be included in other templates
See https://symfony.com/doc/current/templates.html#including-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'
#}
{#
The check is needed to prevent starting the session when looking for "flash messages":
https://symfony.com/doc/current/session.html#avoid-starting-sessions-for-anonymous-users
TIP: With FOSHttpCache you can also adapt this to make it cache safe:
https://foshttpcachebundle.readthedocs.io/en/latest/features/helpers/flash-message.html
#}
{% if app.request.hasPreviousSession %}
<div class="messages">
{% for type, messages in app.flashes %}
{% for message in messages %}
{# Bootstrap alert, see https://getbootstrap.com/docs/3.4/components/#alerts #}
<div class="alert alert-dismissible alert-{{ type }} fade in" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="{{ 'action.close'|trans }}">
<span aria-hidden="true">&times;</span>
</button>
{{ message|trans }}
</div>
{% endfor %}
{% endfor %}
</div>
{% endif %}

View File

@@ -0,0 +1,44 @@
{% extends 'base.html.twig' %}
{% block body_id 'homepage' %}
{#
the homepage is a special page which displays neither a header nor a footer.
this is done with the 'trick' of defining empty Twig blocks without any content
#}
{% block header %}{% endblock %}
{% block footer %}{% endblock %}
{% block body %}
<div class="page-header">
<h1>{{ 'title.homepage'|trans|raw }}</h1>
</div>
<div class="row">
<div class="col-sm-6">
<div class="jumbotron">
<p>
{{ 'help.browse_app'|trans|raw }}
</p>
<p>
<a class="btn btn-primary btn-lg" href="{{ path('blog_index') }}">
<i class="fa fa-users" aria-hidden="true"></i> {{ 'action.browse_app'|trans }}
</a>
</p>
</div>
</div>
<div class="col-sm-6">
<div class="jumbotron">
<p>
{{ 'help.browse_admin'|trans|raw }}
</p>
<p>
<a class="btn btn-primary btn-lg" href="{{ path('admin_index') }}">
<i class="fa fa-lock" aria-hidden="true"></i> {{ 'action.browse_admin'|trans }}
</a>
</p>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,26 @@
{#
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 https://symfony.com/doc/current/form/create_custom_field_type.html#creating-the-form-type-template
#}
{% block date_time_picker_widget %}
<div class="input-group date" data-toggle="datetimepicker">
{{ block('datetime_widget') }}
<span class="input-group-addon">
<span class="fa fa-calendar" aria-hidden="true"></span>
</span>
</div>
{% endblock %}
{% block tags_input_widget %}
<div class="input-group">
{{ form_widget(form, {'attr': {'data-toggle': 'tagsinput', 'data-tags': tags|json_encode}}) }}
<span class="input-group-addon">
<span class="fa fa-tags" aria-hidden="true"></span>
</span>
</div>
{% endblock %}

View File

@@ -0,0 +1,16 @@
{% extends 'bootstrap_3_layout.html.twig' %}
{# Errors #}
{% block form_errors -%}
{% if errors|length > 0 -%}
{% if form is not rootform %}<span class="help-block">{% else %}<div class="alert alert-danger">{% endif %}
<ul class="list-unstyled">
{%- for error in errors -%}
{# use font-awesome icon library #}
<li><span class="fa fa-exclamation-triangle"></span> {{ error.message }}</li>
{%- endfor -%}
</ul>
{% if form is not rootform %}</span>{% else %}</div>{% endif %}
{%- endif %}
{%- endblock form_errors %}

View File

@@ -0,0 +1,94 @@
{% extends 'base.html.twig' %}
{% block body_id 'login' %}
{% block javascripts %}
{{ parent() }}
{{ encore_entry_script_tags('login') }}
{% endblock %}
{% block main %}
{% if error %}
<div class="alert alert-danger">
{{ error.messageKey|trans(error.messageData, 'security') }}
</div>
{% endif %}
<div class="row">
<div class="col-sm-5">
<div class="well">
<form action="{{ path('security_login') }}" method="post">
<fieldset>
<legend><i class="fa fa-lock" aria-hidden="true"></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="_target_path" value="{{ app.request.get('redirect_to') }}"/>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}"/>
<button type="submit" class="btn btn-primary">
<i class="fa fa-sign-in" aria-hidden="true"></i> {{ 'action.sign_in'|trans }}
</button>
</fieldset>
</form>
</div>
</div>
<div id="login-help" class="col-sm-7">
<h3>
<i class="hidden-xs fa fa-long-arrow-left" aria-hidden="true"></i>
{{ 'help.login_users'|trans }}
</h3>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th scope="col">{{ 'label.username'|trans }}</th>
<th scope="col">{{ 'label.password'|trans }}</th>
<th scope="col">{{ 'label.role'|trans }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>john_user</td>
<td>kitten</td>
<td><code>ROLE_USER</code> ({{ 'help.role_user'|trans }})</td>
</tr>
<tr>
<td>jane_admin</td>
<td>kitten</td>
<td><code>ROLE_ADMIN</code> ({{ 'help.role_admin'|trans }})</td>
</tr>
</tbody>
</table>
<div id="login-users-help" class="panel panel-default">
<div class="panel-body">
<p>
<span class="label label-success">{{ 'note'|trans }}</span>
{{ 'help.reload_fixtures'|trans }}<br/>
<code class="console">$ php bin/console doctrine:fixtures:load</code>
</p>
<p>
<span class="label label-success">{{ 'tip'|trans }}</span>
{{ 'help.add_user'|trans }}<br/>
<code class="console">$ php bin/console app:add-user</code>
</p>
</div>
</div>
</div>
</div>
{% endblock %}
{% block sidebar %}
{{ parent() }}
{{ show_source_code(_self) }}
{% endblock %}

View File

@@ -0,0 +1,29 @@
{% extends 'base.html.twig' %}
{% block body_id 'user_password' %}
{% block main %}
<h1>{{ 'title.change_password'|trans }}</h1>
<div class="alert alert-info" role="alert">{{ 'info.change_password'|trans }}</div>
{{ form_start(form) }}
{{ form_widget(form) }}
<button type="submit" class="btn btn-primary">
<i class="fa fa-save" aria-hidden="true"></i> {{ 'action.save'|trans }}
</button>
{{ form_end(form) }}
{% endblock %}
{% block sidebar %}
<div class="section">
<a href="{{ path('user_edit') }}" class="btn btn-lg btn-block btn-danger">
<i class="fa fa-edit" aria-hidden="true"></i> {{ 'action.edit_user'|trans }}
</a>
</div>
{{ parent() }}
{{ show_source_code(_self) }}
{% endblock %}

View File

@@ -0,0 +1,27 @@
{% extends 'base.html.twig' %}
{% block body_id 'user_edit' %}
{% block main %}
<h1>{{ 'title.edit_user'|trans }}</h1>
{{ form_start(form) }}
{{ form_widget(form) }}
<button type="submit" class="btn btn-primary">
<i class="fa fa-save" aria-hidden="true"></i> {{ 'action.save'|trans }}
</button>
{{ form_end(form) }}
{% endblock %}
{% block sidebar %}
<div class="section">
<a href="{{ path('user_change_password') }}" class="btn btn-lg btn-block btn-danger">
<i class="fa fa-lock" aria-hidden="true"></i> {{ 'action.change_password'|trans }}
</a>
</div>
{{ parent() }}
{{ show_source_code(_self) }}
{% endblock %}