[TWIG] Improved templates HTML structure, removed unnecessary element nesting, and refactored content sectioning

[COMPONENTS][Search] Refactored widget event as 'PrependRightPanel' (making it able to accomodate more generic blocks)
This commit is contained in:
Eliseu Amaro 2022-01-17 16:32:41 +00:00 committed by Hugo Sales
parent 242fe3fd6e
commit 692ecf1c99
Signed by: someonewithpc
GPG Key ID: 7D0C7EAFC9D835A0
17 changed files with 224 additions and 155 deletions

View File

@ -89,7 +89,7 @@ class Attachment extends Controller
try { try {
return $this->attachment($attachment_id, $note_id, function ($res) use ($note_id, $attachment_id) { return $this->attachment($attachment_id, $note_id, function ($res) use ($note_id, $attachment_id) {
return [ return [
'_template' => '/cards/attachments/show.html.twig', '_template' => '/cards/attachments/view.html.twig',
'download' => $res['attachment']->getDownloadUrl(note: $note_id), 'download' => $res['attachment']->getDownloadUrl(note: $note_id),
'title' => $res['title'], 'title' => $res['title'],
'attachment' => $res['attachment'], 'attachment' => $res['attachment'],

View File

@ -14,46 +14,44 @@
{% endfor %} {% endfor %}
{% if notes is defined %} {% if notes is defined %}
<section> <article>
<header class="feed-header"> <header class="feed-header">
{% if page_title is defined %} {% if page_title is defined %}
<h1 class="heading-no-margin">{{ page_title | trans }}</h1> <h1 class="heading-no-margin">{{ page_title | trans }}</h1>
{% else %} {% else %}
<h1 class="heading-no-margin">{{ 'Notes' | trans }}</h1> <h1 class="heading-no-margin">{{ 'Notes' | trans }}</h1>
{% endif %}
<nav class="feed-actions">
<details class="feed-actions-details">
<summary>
{{ icon('filter', 'icon icon-feed-actions') | raw }} {# button-container #}
</summary>
<div class="feed-actions-details-dropdown">
<ul>
{% for block in handle_event('AddFeedActions', app.request, notes is defined and notes is not empty) %}
{{ block | raw }}
{% endfor %}
</ul>
</div>
</details>
</nav>
</header>
{% if notes is not empty %}
{# Backwards compatibility with hAtom 0.1 #}
<main class="feed" tabindex="0" role="feed">
<div class="h-feed hfeed notes">
{% for conversation in notes %}
{% block current_note %}
{% if conversation is instanceof('array') %}
{{ noteView.macro_note(conversation['note'], conversation['replies']) }}
{% else %}
{{ noteView.macro_note(conversation) }}
{% endif %}
<hr tabindex="0" title="{{ 'End of note and replies.' | trans }}">
{% endblock current_note %}
{% endfor %}
</div>
</main>
{% endif %} {% endif %}
<nav class="feed-actions">
<details class="feed-actions-details">
<summary>
{{ icon('filter', 'icon icon-feed-actions') | raw }} {# button-container #}
</summary>
<div class="feed-actions-details-dropdown">
<menu>
{% for block in handle_event('AddFeedActions', app.request, notes is defined and notes is not empty) %}
{{ block | raw }}
{% endfor %}
</menu>
</div>
</details>
</nav>
</header>
{% if notes is not empty %}
{# Backwards compatibility with hAtom 0.1 #}
<section class="feed h-feed hfeed notes" tabindex="0" role="feed">
{% for conversation in notes %}
{% block current_note %}
{% if conversation is instanceof('array') %}
{{ noteView.macro_note(conversation['note'], conversation['replies']) }}
{% else %}
{{ noteView.macro_note(conversation) }}
{% endif %}
<hr tabindex="0" title="{{ 'End of note and replies.' | trans }}">
{% endblock current_note %}
{% endfor %}
</section> </section>
{% endif %}
</article>
{% endif %} {% endif %}
{% endblock body %} {% endblock body %}

View File

@ -77,7 +77,7 @@ class LeftPanel extends Component
*/ */
public function onEndShowStyles(array &$styles, string $route): bool public function onEndShowStyles(array &$styles, string $route): bool
{ {
$styles[] = 'components/Left/assets/css/view.css'; $styles[] = 'components/LeftPanel/assets/css/view.css';
return Event::next; return Event::next;
} }
} }

View File

@ -1,25 +1,28 @@
{% block leftpanel %} {% block leftpanel %}
<a id="anchor-left-panel" class="anchor-hidden" title="{{ 'Press tab followed by a space to access left panel' | trans }}"></a> <section class="section-panel-left">
<label class="panel-left-icon" for="panel-left-toggle" <a id="anchor-left-panel" class="anchor-hidden"
tabindex="-1">{{ icon('menu', 'icon icon-left') | raw }}</label> title="{{ 'Press tab followed by a space to access left panel' | trans }}"></a>
<input type="checkbox" id="panel-left-toggle" tabindex="0" title="{{ 'Open right panel' | trans }}"> <label class="panel-left-icon" for="panel-left-toggle"
tabindex="-1">{{ icon('menu', 'icon icon-left') | raw }}</label>
<input type="checkbox" id="panel-left-toggle" tabindex="0" title="{{ 'Open right panel' | trans }}">
<section class="header-panel section-panel-left"> <aside class="header-panel">
<aside class="panel-content accessibility-target"> <article class="panel-content accessibility-target">
{% if app.user %} {% if app.user %}
<section class='section-widget section-padding' title="{{ 'Your profile information.' | trans }}"> <section class='section-widget section-padding' title="{{ 'Your profile information.' | trans }}">
{% block profile_view %}{% include 'cards/profile/view.html.twig' with { actor: current_actor } %}{% endblock profile_view %} {% block profile_view %}{% include 'cards/profile/view.html.twig' with { actor: current_actor } %}{% endblock profile_view %}
{{ block("profile_current_actor", "cards/navigation/view.html.twig") }} {{ block("profile_current_actor", "cards/navigation/view.html.twig") }}
</section> </section>
{% else %} {% else %}
<section> <section>
{{ block("profile_security", "cards/navigation/view.html.twig") }} {{ block("profile_security", "cards/navigation/view.html.twig") }}
</section> </section>
{% endif %} {% endif %}
{{ block("feeds", "cards/navigation/view.html.twig") }} {{ block("feeds", "cards/navigation/view.html.twig") }}
{{ block("footer", "cards/navigation/view.html.twig") }} {{ block("footer", "cards/navigation/view.html.twig") }}
</article>
</aside> </aside>
</section> </section>
{% endblock leftpanel %} {% endblock leftpanel %}

View File

@ -35,7 +35,7 @@ class RightPanel extends Component
*/ */
public function onEndShowStyles(array &$styles, string $route): bool public function onEndShowStyles(array &$styles, string $route): bool
{ {
$styles[] = 'components/Right/assets/css/view.css'; $styles[] = 'components/RightPanel/assets/css/view.css';
return Event::next; return Event::next;
} }
} }

View File

@ -1,31 +1,38 @@
{% block rightpanel %} {% block rightpanel %}
<a id="anchor-right-panel" class="anchor-hidden" title="{{ 'Press tab followed by a space to access right panel' | trans }}"></a> <section class="section-panel-right">
<label class="panel-right-icon" for="panel-right-toggle" <a id="anchor-right-panel" class="anchor-hidden"
tabindex="-1">{{ icon('chevron-left', 'icon icon-right') | raw }}</label> title="{{ 'Press tab followed by a space to access right panel' | trans }}"></a>
<input type="checkbox" id="panel-right-toggle" tabindex="0" title="{{ 'Open right panel' | trans }}"> <label class="panel-right-icon" for="panel-right-toggle"
tabindex="-1">{{ icon('chevron-left', 'icon icon-right') | raw }}</label>
<input type="checkbox" id="panel-right-toggle" tabindex="0" title="{{ 'Open right panel' | trans }}">
<div class="header-panel section-panel-right"> <aside class="header-panel">
<aside class="panel-content accessibility-target"> <article class="panel-content accessibility-target">
<section>
{% set prepend_right_panel = handle_event('PrependRightPanel', request) %}
{% for widget in prepend_right_panel %}
{{ widget | raw }}
{% endfor %}
</section>
{% set current_path = app.request.get('_route') %} {% set current_path = app.request.get('_route') %}
{% set blocks = handle_event('AppendRightPostingBlock', request) %} {% set blocks = handle_event('AppendRightPostingBlock', request) %}
{% if blocks['post_form'] is defined %} {% if blocks['post_form'] is defined %}
<section class="section-widget" title="{{ 'Create a new note.' | trans }}"> <section class="section-widget" title="{{ 'Create a new note.' | trans }}">
<details class="section-widget-title-details" open="open" <details class="section-widget-title-details" open="open"
title="{{ 'Expand if you want to access more options.' | trans }}"> title="{{ 'Expand if you want to access more options.' | trans }}">
<summary class="section-title-summary"> <summary class="section-title-summary">
<h2> <h2>
{% set current_path = app.request.get('_route') %} {% set current_path = app.request.get('_route') %}
{% if current_path == 'conversation_reply_to' %} {% if current_path == 'conversation_reply_to' %}
{{ "Reply to note" | trans }} {{ "Reply to note" | trans }}
{% else %} {% else %}
{{ "Create a note" | trans }} {{ "Create a note" | trans }}
{% endif %} {% endif %}
</h2> </h2>
</summary> </summary>
<div class="section-form"> <fieldset class="section-form">
<fieldset>
{{ form_start(blocks['post_form']) }} {{ form_start(blocks['post_form']) }}
{{ form_errors(blocks['post_form']) }} {{ form_errors(blocks['post_form']) }}
{% if blocks['post_form'].in is defined %} {% if blocks['post_form'].in is defined %}
@ -48,15 +55,15 @@
{{ form_rest(blocks['post_form']) }} {{ form_rest(blocks['post_form']) }}
{{ form_end(blocks['post_form']) }} {{ form_end(blocks['post_form']) }}
</fieldset> </fieldset>
</div> </details>
</details> </section>
</section> {% endif %}
{% endif %}
{% set extra_blocks = get_right_panel_blocks({'path': current_path, 'request': app.request, 'vars': (right_panel_vars | default)}) %} {% set extra_blocks = get_right_panel_blocks({'path': current_path, 'request': app.request, 'vars': (right_panel_vars | default)}) %}
{% for block in extra_blocks %} {% for block in extra_blocks %}
{{ block | raw }} {{ block | raw }}
{% endfor %} {% endfor %}
</article>
</aside> </aside>
</div> </section>
{% endblock rightpanel %} {% endblock rightpanel %}

View File

@ -130,7 +130,7 @@ class Search extends FeedController
} }
return [ return [
'_template' => 'search/show.html.twig', '_template' => 'search/view.html.twig',
'actor' => $actor, 'actor' => $actor,
'search_form' => Comp\Search::searchForm($request, query: $q, add_subscribe: !\is_null($actor)), 'search_form' => Comp\Search::searchForm($request, query: $q, add_subscribe: !\is_null($actor)),
'search_builder_form' => $search_builder_form->createView(), 'search_builder_form' => $search_builder_form->createView(),

View File

@ -29,6 +29,7 @@ use function App\Core\I18n\_m;
use App\Core\Modules\Component; use App\Core\Modules\Component;
use App\Util\Common; use App\Util\Common;
use App\Util\Exception\RedirectException; use App\Util\Exception\RedirectException;
use App\Util\Formatting;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormView; use Symfony\Component\Form\FormView;
@ -83,7 +84,7 @@ class Search extends Component
'label' => _m('Search'), 'label' => _m('Search'),
'attr' => [ 'attr' => [
//'class' => 'button-container search-button-container', //'class' => 'button-container search-button-container',
'title' => _m('Query notes for specific tags.'), 'title' => _m('Perform search'),
], ],
], ],
]; ];
@ -119,9 +120,9 @@ class Search extends Component
* *
* @throws RedirectException * @throws RedirectException
*/ */
public function onAddExtraHeaderForms(Request $request, array &$elements) public function onPrependRightPanel(Request $request, array &$elements)
{ {
$elements[] = self::searchForm($request); $elements[] = Formatting::twigRenderFile('cards/search/view.html.twig', ['search' => self::searchForm($request)]);
return Event::next; return Event::next;
} }

View File

@ -0,0 +1,8 @@
<section title="{{ 'Search for notes, actors, and beyond' | trans }}">
<fieldset class="section-form form-search">
{{ form_start(search) }}
<span>{{ form_row(search.search_query) }}{{ form_row(search.submit_search) }}</span>
{{ form_rest(search) }}
{{ form_end(search) }}
</fieldset>
</section>

View File

@ -188,18 +188,25 @@ embed header {
} }
.note-actions { .note-actions {
display: flex; display: inline-block;
align-items: center; align-items: center;
margin-left: auto; margin-left: auto;
} }
.note-actions ul { .note-actions > li {
display: flex; display: inline-block;
vertical-align: middle; margin-left: 2px;
margin-right: 2px;
} }
.note-actions ul > li { .note-actions-separator {
margin-left: 8px; display: inline-block;
background: var(--foreground);
opacity: 0.33;
width: 1px;
height: 1em;
margin-left: 2px;
margin-right: 2px;
} }
.note-actions-extra-details { .note-actions-extra-details {

View File

@ -35,8 +35,10 @@ hr {
background-color: var(--border) !important; background-color: var(--border) !important;
} }
ol, menu,
ul { ul {
padding: unset;
margin: unset;
list-style: none; list-style: none;
} }

View File

@ -272,6 +272,46 @@ textarea.form-row-widget {
resize: vertical; resize: vertical;
} }
.form-search {
display: inline-block;
padding-left: unset;
padding-right: unset;
padding-bottom: unset;
margin-bottom: var(--m);
}
.form-search label {
display: block;
opacity: 0;
width: 0;
height: 0;
}
.form-search span {
display: inline-flex;
width: 100%;
}
.form-search .form-row {
margin-bottom: unset;
width: 100%;
}
.form-search span input[type='text'] {
margin: unset;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
height: 100%;
}
.form-search span button {
margin: unset;
border-left: none !important;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
height: 100%;
}
.alert, .alert,
.alert-danger, .alert-danger,
.form-error, .form-error,

View File

@ -1,6 +1,7 @@
.section-panel-left { .section-panel-left {
position: absolute;
left: 0; left: 0;
} }
@ -12,7 +13,9 @@
.panel-left-icon { .panel-left-icon {
cursor: pointer !important; cursor: pointer !important;
padding-left: var(--s);
border: 2px solid transparent; border: 2px solid transparent;
vertical-align: middle;
} }
.profile-navigation { .profile-navigation {
@ -66,8 +69,12 @@
/* > 720p */ /* > 720p */
@media only screen and (min-width:1281px) { @media only screen and (min-width:1281px) {
.section-panel-left #panel-left-toggle ~ .header-panel {
left: 0;
}
.panel-left-icon { .panel-left-icon {
display: none; opacity: 0;
} }
} }

View File

@ -1,6 +1,7 @@
.section-panel-right { .section-panel-right {
position: absolute;
right: 0; right: 0;
} }
@ -10,10 +11,15 @@
top: -100%; top: -100%;
} }
.section-panel-right #panel-right-toggle:checked ~ .header-panel {
left: 0;
}
.panel-right-icon { .panel-right-icon {
margin-left: var(--m) !important;
cursor: pointer !important; cursor: pointer !important;
padding-right: var(--s);
border: 2px solid transparent; border: 2px solid transparent;
vertical-align: middle;
} }
.section-panel-right textarea { .section-panel-right textarea {
@ -21,8 +27,12 @@
} }
@media only screen and (min-width: 1281px) { @media only screen and (min-width: 1281px) {
.section-panel-right #panel-right-toggle ~ .header-panel {
right: 0;
}
.panel-right-icon { .panel-right-icon {
display: none; opacity: 0;
} }
} }

View File

@ -95,8 +95,6 @@
</aside> </aside>
{% block header %} {% block header %}
{% set extra_header_forms = handle_event('AddExtraHeaderForms', request) %}
<header class="page-header"> <header class="page-header">
{{ block("leftpanel", "stdgrid.html.twig") }} {{ block("leftpanel", "stdgrid.html.twig") }}
@ -107,22 +105,11 @@
<h1>{{ icon('logo', 'icon icon-logo') | raw }}{{ config('site', 'name') }}</h1> <h1>{{ icon('logo', 'icon icon-logo') | raw }}{{ config('site', 'name') }}</h1>
</a> </a>
<details class="header-extra-actions">
<summary>
{{ icon('kebab', 'icon icon-details-open') | raw }}
</summary>
<div class="header-extra-actions-open">
{% for extra_form in extra_header_forms %}
{{ form(extra_form) }}
{% endfor %}
</div>
</details>
{{ block("rightpanel", "stdgrid.html.twig") }} {{ block("rightpanel", "stdgrid.html.twig") }}
</header> </header>
{% endblock header %} {% endblock header %}
<div class="page-content-wrapper"> <main class="page-content-wrapper">
<a role="navigation" rel="help" id="anchor-main-content" class="anchor-hidden" <a role="navigation" rel="help" id="anchor-main-content" class="anchor-hidden"
title="{{ 'Press tab to access main content.' | trans }}"></a> title="{{ 'Press tab to access main content.' | trans }}"></a>
<div class='page-content accessibility-target'> <div class='page-content accessibility-target'>
@ -130,7 +117,7 @@
{% block body %}{% endblock %} {% block body %}{% endblock %}
{% block javascripts %}{% endblock javascripts %} {% block javascripts %}{% endblock javascripts %}
</div> </div>
</div> </main>
</body> </body>
</html> </html>

View File

@ -1,42 +1,42 @@
{% block note_actions %} {% block note_actions %}
{% if app.user or note_actions_hide is defined %} {% if app.user or note_actions_hide is defined %}
<div class="note-actions note-info-end"> <menu class="note-actions note-info-end">
<ul> <li class="note-actions-extra">
<li class="note-actions-extra"> <details class="note-actions-extra-details">
<details class="note-actions-extra-details"> <summary>
<summary> {{ icon('kebab', 'icon icon-note-actions-extra') | raw }} {# button-container #}
{{ icon('kebab', 'icon icon-note-actions-extra') | raw }} {# button-container #} </summary>
</summary> <ul>
<ul> <li>
<a href="{{ note.getUrl() }}">{{ 'Permalink' | trans }}</a>
</li>
<hr>
{% for current_action in get_extra_note_actions(note) %}
<li> <li>
<a href="{{ note.getUrl() }}">{{ 'Permalink' | trans }}</a> <a class="{{ current_action["classes"] }}"
href="{{ current_action["url"] }}">{{ current_action['title'] }}</a>
</li> </li>
<hr> {% endfor %}
{% for current_action in get_extra_note_actions(note) %} </ul>
<li> </details>
<a class="{{ current_action["classes"] }}" </li>
href="{{ current_action["url"] }}">{{ current_action['title'] }}</a> <span class="note-actions-separator"></span>
</li> {% for current_action in get_note_actions(note) %}
{% endfor %} <li>
</ul> <a title="{{ current_action["title"] | trans }}"
</details> class="{{ current_action["classes"] }}"
href="{{ current_action["url"] }}"></a>
</li> </li>
{% for current_action in get_note_actions(note) %} {% endfor %}
<li> </menu>
<a title="{{ current_action["title"] | trans }}"
class="{{ current_action["classes"] }}"
href="{{ current_action["url"] }}"></a>
</li>
{% endfor %}
</ul>
</div>
{% endif %} {% endif %}
{% endblock note_actions %} {% endblock note_actions %}
{% block note_replies %} {% block note_replies %}
{% if replies is defined and replies is not empty %} {% if replies is defined and replies is not empty %}
<div class="u-in-reply-to replies"> <div class="u-in-reply-to replies">
<span class="note-replies-start" tabindex="0">{{ 'Replies to ' | trans }}{{ nickname }}{{ '\'s note' | trans }}</span> <span class="note-replies-start"
tabindex="0">{{ 'Replies to ' | trans }}{{ nickname }}{{ '\'s note' | trans }}</span>
{% for conversation in replies %} {% for conversation in replies %}
{{ _self.macro_note(conversation['note'], conversation['replies']) }} {{ _self.macro_note(conversation['note'], conversation['replies']) }}
<hr tabindex="0" title="{{ 'End of reply' | trans }}"> <hr tabindex="0" title="{{ 'End of reply' | trans }}">
@ -158,10 +158,10 @@
class="h-entry hentry note" lang={{ note.getLanguageLocale() }}> class="h-entry hentry note" lang={{ note.getLanguageLocale() }}>
{{ block('note_sidebar') }} {{ block('note_sidebar') }}
<div class="note-wrapper"> <div class="note-wrapper">
<div class="note-info"> <header class="note-info">
{{ block('note_info') }} {{ block('note_info') }}
{{ block('note_actions') }} {{ block('note_actions') }}
</div> </header>
<section role="dialog" class="e-content entry-content note-content"> <section role="dialog" class="e-content entry-content note-content">
{{ block('note_text') }} {{ block('note_text') }}
@ -171,7 +171,6 @@
{{ block('note_replies') }} {{ block('note_replies') }}
{{ block('note_complementary_info') }} {{ block('note_complementary_info') }}
</div> </div>
</article> </article>
{% endmacro macro_note %} {% endmacro macro_note %}
@ -187,9 +186,9 @@
<article class="h-entry hentry note" lang={{ note.getLanguageLocale() }}> <article class="h-entry hentry note" lang={{ note.getLanguageLocale() }}>
{{ block('note_sidebar') }} {{ block('note_sidebar') }}
<div class="note-wrapper"> <div class="note-wrapper">
<div class="note-info"> <header class="note-info">
{{ block('note_info') }} {{ block('note_info') }}
</div> </header>
<section role="dialog" class="e-content entry-content note-content"> <section role="dialog" class="e-content entry-content note-content">
{{ block('note_text') }} {{ block('note_text') }}