Add taxonomy submenus

This commit is contained in:
Tetrakern 2024-08-06 22:04:52 +02:00
parent a5bbe51a8a
commit ee7da8b4ff
11 changed files with 308 additions and 7 deletions

View File

@ -194,6 +194,25 @@ The theme has two menu locations: Navigation and Footer Menu. You can create and
* `hide-if-logged-in` - Hides the menu item if the user is logged in.
* `hide-if-logged-out` - Hides the menu item if the user is logged out.
### Taxonomy Submenus
In addition to the Taxonomies page template, you can also add a submenu for each taxonomy in the main navigation. This works for categories, tags, genres, fandoms, characters, and warnings. To do this, add a custom link as a menu item with `#` as the link, then assign it **one** of the following trigger CSS classes (check the screen options if you cannot see the input). This should work on all levels, but it is recommended to keep it at the top level. The menu link and submenu will only be visible on desktop viewports.
**Menu classes:**
* `trigger-term-menu-categories` - Submenu for categories.
* `trigger-term-menu-tags` - Submenu for tags.
* `trigger-term-menu-genres` - Submenu for genres.
* `trigger-term-menu-fandoms` - Submenu for fandoms.
* `trigger-term-menu-characters` - Submenu for characters.
* `trigger-term-menu-warnings` - Submenu for warnings.
**Optional CSS classes:**
* `columns-2|4|5` - Change the number of columns to 2, 4, or 5 (default is 3).
![Genres Submenu Setup](repo/assets/menu_custom_link_genres_submenu.png?raw=true)
![Genres Submenu](repo/assets/genres_submenu.png?raw=true)
## Sidebar
You can enable the optional sidebar under **Appearance > Customize > Layout**, choosing either left or right alignment along with other options. Typically, this also requires some manual adjustments to the layout. Increasing the site width is recommended to accommodate the new column; 1100px is a good start for a 256px wide sidebar. Note that the sidebar will only show up once you add widgets to it.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1011,3 +1011,121 @@ function fictioneer_mu_registration_end( $args ) {
if ( FICTIONEER_MU_REGISTRATION ) {
add_action( 'fictioneer_after_main', 'fictioneer_mu_registration_end', 999 );
}
// =============================================================================
// TAXONOMY SUBMENU (HOOKED IN NAVIGATION PARTIAL)
// =============================================================================
/**
* Outputs the <template> HTML for the taxonomy submenu
*
* Note: The ID of the template element is "term-submenu-{$type}".
*
* @since 5.22.1
*
* @param string $type Optional. The taxonomy type to build the menu for. Default 'fcn_genre'.
* @param bool $hide_empty Optional. Whether to include empty taxonomies. Default true.
*/
function fictioneer_render_taxonomy_submenu( $type = 'fcn_genre', $hide_empty = true ) {
// Query terms
$terms = get_terms(
apply_filters(
'fictioneer_filter_taxonomy_submenu_query_args',
array( 'taxonomy' => $type, 'hide_empty' => $hide_empty ),
$type
)
);
// All good?
if ( is_wp_error( $terms ) ) {
return;
}
// Setup
$nice_type = str_replace( 'fcn_', '', $type );
$taxonomy = get_taxonomy( $type );
$html = '';
// Build HTML
$html = "<template id='term-submenu-{$type}'><div class='sub-menu nav-terms-submenu _{$nice_type}'>";
$html .= '<div class="nav-terms-submenu__note">';
$html .= apply_filters(
'fictioneer_filter_taxonomy_submenu_note',
sprintf( __( 'Choose a %s to browse', 'fictioneer' ), $taxonomy->labels->singular_name ),
$taxonomy
);
$html .= '</div><div class="nav-terms-submenu__wrapper">';
foreach ( $terms as $term ) {
$link = esc_url( get_term_link( $term ) );
$name = esc_html( $term->name );
$html .= "<a href='{$link}' class='nav-term-item _{$nice_type} _no-menu-item-style' data-type='{$type}' data-term-id='{$term->term_id}'>{$name}</a>";
}
$html .= '</div></div></template>';
// Render
echo apply_filters( 'fictioneer_filter_taxonomy_submenu_html', $html, $terms, $type, $hide_empty );
}
/**
* Action wrapper for the category submenu
*
* @since 5.22.1
*/
function fictioneer_render_category_submenu() {
fictioneer_render_taxonomy_submenu( $type = 'category' );
}
/**
* Action wrapper for the tag submenu
*
* @since 5.22.1
*/
function fictioneer_render_tag_submenu() {
fictioneer_render_taxonomy_submenu( $type = 'post_tag' );
}
/**
* Action wrapper for the genre submenu
*
* @since 5.22.1
*/
function fictioneer_render_genre_submenu() {
fictioneer_render_taxonomy_submenu( $type = 'fcn_genre' );
}
/**
* Action wrapper for the fandom submenu
*
* @since 5.22.1
*/
function fictioneer_render_fandom_submenu() {
fictioneer_render_taxonomy_submenu( $type = 'fcn_fandom' );
}
/**
* Action wrapper for the character submenu
*
* @since 5.22.1
*/
function fictioneer_render_character_submenu() {
fictioneer_render_taxonomy_submenu( $type = 'fcn_character' );
}
/**
* Action wrapper for the warning submenu
*
* @since 5.22.1
*/
function fictioneer_render_warning_submenu() {
fictioneer_render_taxonomy_submenu( $type = 'fcn_content_warning' );
}

File diff suppressed because one or more lines are too long

8
js/complete.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -90,6 +90,30 @@ if ( $header_style === 'wide' ) {
}
}
if ( strpos( $menu, 'trigger-term-menu-categories' ) !== false ) {
add_action( 'wp_footer', 'fictioneer_render_category_submenu' );
}
if ( strpos( $menu, 'trigger-term-menu-tags' ) !== false ) {
add_action( 'wp_footer', 'fictioneer_render_tag_submenu' );
}
if ( strpos( $menu, 'trigger-term-menu-genres' ) !== false ) {
add_action( 'wp_footer', 'fictioneer_render_genre_submenu' );
}
if ( strpos( $menu, 'trigger-term-menu-fandoms' ) !== false ) {
add_action( 'wp_footer', 'fictioneer_render_fandom_submenu' );
}
if ( strpos( $menu, 'trigger-term-menu-characters' ) !== false ) {
add_action( 'wp_footer', 'fictioneer_render_character_submenu' );
}
if ( strpos( $menu, 'trigger-term-menu-warning' ) !== false ) {
add_action( 'wp_footer', 'fictioneer_render_warning_submenu' );
}
echo $menu;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -492,8 +492,59 @@ document.addEventListener('DOMContentLoaded', () => {
nav.classList.add('_oversized-navigation');
}
}
_$$('.main-navigation .trigger-term-menu-categories').forEach(element => {
fcn_appendTermMenu('category', element);
});
_$$('.main-navigation .trigger-term-menu-tags').forEach(element => {
fcn_appendTermMenu('post_tag', element);
});
_$$('.main-navigation .trigger-term-menu-genres').forEach(element => {
fcn_appendTermMenu('fcn_genre', element);
});
_$$('.main-navigation .trigger-term-menu-fandoms').forEach(element => {
fcn_appendTermMenu('fcn_fandom', element);
});
_$$('.main-navigation .trigger-term-menu-characters').forEach(element => {
fcn_appendTermMenu('fcn_character', element);
});
_$$('.main-navigation .trigger-term-menu-warnings').forEach(element => {
fcn_appendTermMenu('fcn_content_warning', element);
});
});
/**
* Append term submenu to navigation menu item.
*
* @since 5.22.1
*
* @param {String} type - The taxonomy type.
* @param {HTMLElement} target - The menu item element.
*/
function fcn_appendTermMenu(type, target) {
const template = _$$$(`term-submenu-${type}`);
if (!template) {
return;
}
const submenu = template.content.cloneNode(true);
target.classList.add('menu-item-has-children');
target.querySelector('[href="#"]').addEventListener('click', event => {
event.preventDefault();
});
target.appendChild(submenu);
}
// =============================================================================
// DETECT SCROLL DIRECTION
// =============================================================================

View File

@ -418,3 +418,92 @@
text-transform: uppercase;
}
}
[class*="trigger-term-menu"] {
display: none;
content-visibility: hidden;
border-radius: var(--layout-border-radius-small) var(--layout-border-radius-small) 0 0;
@include bp(desktop) {
display: block;
content-visibility: visible;
}
&.columns-2 .nav-terms-submenu {
--columns: 2;
}
&.columns-4 .nav-terms-submenu {
--columns: 4;
}
&.columns-5 .nav-terms-submenu {
--columns: 5;
}
> a::after {
content: unicode("f078");
font-family: "Font Awesome 6 Free";
font-size: .75em;
font-weight: 900;
margin: 0 -0.5em 0 .75em;
}
}
.mobile-menu [class*="trigger-term-menu"] {
display: none !important;
content-visibility: hidden !important;
}
.nav-terms-submenu {
--gap: 0px;
--width: 500px;
--columns: 3;
font-family: var(--ff-nav-item);
font-size: 15px;
width: 1000px;
max-width: min(calc(100vw - 20px), calc(var(--width) + var(--gap) * (var(--columns) - 1)));
@include bp(desktop) {
display: block;
content-visibility: visible;
}
&__note {
text-transform: uppercase;
font-family: var(--ff-note);
font-size: 12px;
font-weight: 600;
padding: .75rem 1rem 0;
opacity: .5;
}
&__wrapper {
display: grid;
grid-gap: var(--gap);
grid-template-columns: repeat(auto-fit, minmax(min(100%, calc((var(--width) - var(--gap) * (var(--columns) - 1)) / var(--columns))), 1fr));
background: var(--navigation-submenu-background);
padding-top: .5rem;
border-radius: 0 0 var(--layout-border-radius-small) var(--layout-border-radius-small);
overflow: hidden;
}
.nav-term-item {
line-height: var(--navigation-height);
white-space: nowrap;
text-overflow: ellipsis;
padding: 0 1rem;
height: var(--navigation-height);
max-width: 100%;
overflow: hidden;
}
:where(a, label, button) {
color: var(--navigation-subitem-color, var(--navigation-color));
&:hover {
background: var(--navigation-subitem-background-hover);
color: var(--navigation-subitem-color-hover, var(--navigation-color-hover));
}
}
}