This commit is contained in:
2023-01-26 20:55:52 +00:00
parent 33f604f5cb
commit 7bd647a7a0
109 changed files with 19909 additions and 15092 deletions

18
src/404.php Normal file
View File

@@ -0,0 +1,18 @@
<?php get_header(); ?>
<main class="page">
<section class="page__logo">
<?php get_template_part('partials/logo') ?>
</section>
<section class="page__content">
<h1 class="title">404 - Page not found</h1>
<a class="link" href="<?php echo get_site_url() ?>/">Go back home</a>
</section>
<section class="page__banner">
<?php get_template_part('partials/banner') ?>
</section>
<section class="page__footer">
<?php get_template_part('partials/footer') ?>
</section>
</main>
<?php get_template_part('partials/navigation') ?>
<?php get_footer() ?>

View File

@@ -0,0 +1,49 @@
<?php
class Windycoys_Walker_Comments extends Walker_Comment {
function start_lvl(&$output, $depth = 0, $args = Array()) {
$output .= '<ol class="comments__list comments__list--sub-list">';
}
function end_lvl(&$output, $depth = 0, $args = Array()) {
$output .= '</ol>';
}
function start_el(&$output, $comment, $depth = 0 , $args = Array(), $id = 0) {
$id = $comment->comment_ID;
$post_id = $comment->comment_post_ID;
$reply_link = get_permalink($post_id) . '?replytocom='.$id.'#respond';
$author_email = $comment->comment_author_email;
$author = $comment->comment_author;
$avatar = get_avatar($comment, 128);
$date = get_comment_date(get_option('date_format'), $id).' at '.get_comment_date(get_option('time_format'), $id);
$content = $comment->comment_content;
$output .= '<li class="comments__item">';
$output .= '<div class="comment">';
$output .= '<div class="comment__head">';
$output .= sprintf('<div class="comment__avatar has-silhouette">%s</div>', $avatar);
$output .= '<div class="comment__metadata">';
$output .= sprintf('<span class="comment__author">%s</span>', $author);
$output .= sprintf('<span class="comment__date">%s</span>', $date);
$output .= '</div></div>';
$output .= sprintf('<div class="comment__body">%s</div>', $content);
$output .= '<div class="comment__foot">';
$output .= sprintf('<a class="comment__reply" data-comment-author="%s" ' .
'data-comment-id="%s" href="%s">',
$author,
$id,
$reply_link
);
$output .= '<span class="comment__reply-icon">';
$output .= '<svg class="icon icon--extra-small"><use href="#icon-reply"></use></svg></span>';
$output .= '<span class="comment__reply-text">Reply</span></a>';
$output .= '<div class="comment__inline-reply"></div>';
$output .= '</div></div>';
}
function end_el(&$output, $comment, $depth = 0, $args = Array()) {
$output .= '</li>';
}
}
?>

View File

@@ -0,0 +1,28 @@
<?php
class Windycoys_Walker_Navigation extends Walker_Nav_Menu {
function start_lvl(&$output, $depth = 0, $args = Array()) {
$output .= '<ul class="nav__list" role="menu">';
}
function end_lvl(&$output, $depth = 0, $args = Array()) {
$output .= '</ul>';
}
function start_el(&$output, $item, $depth = 0, $args = Array(), $id = 0) {
$title = $item->title;
$url = $item->url;
if ($title && $url) {
$output .= '<li class="nav__list-item" role="none">';
$output .= sprintf('<a class="nav__link" href="%s" role="menuitem">', $url);
$output .= $title;
$output .= '</a>';
}
}
function end_el(&$output, $item, $depth = 0, $args = Array()) {
$output .= '</li>';
}
}
?>

50
src/comments.php Normal file
View File

@@ -0,0 +1,50 @@
<?php
require get_template_directory() . '/classes/walker.comments.php';
$form_settings = array(
"class_form" => 'comment-respond__form',
"class_submit" => 'comment-respond__submit',
"comment_field" => '<div class="comment-respond__item comment-respond__item--large"><label class="comment-respond__label" for="comment">Comment</label><textarea class="comment-respond__input" id="comment" name="comment" cols="25" rows="8" aria-required="true"></textarea></div>',
"logged_in_as" => '<p class="comment-respond__text">' . sprintf( __( 'Logged in as <a class="link" href="%1$s">%2$s</a>. <a class="link" href="%3$s" title="Log out of this account">Log out?</a>' ), admin_url( 'profile.php' ), $user_identity, wp_logout_url( apply_filters( 'the_permalink', get_permalink( ) ) ) ) . '</p>',
"title_reply_before" => '<h3 id="reply-title" class="comment-respond__title">',
"title_reply" => '<span class="comment-respond__title-text">Reply</span>',
"cancel_reply_before" => '<span class="comment-respond__cancel">',
"cancel_reply_after" => '</span>',
"comment_notes_before" => '<p class="comment-respond__notes">' . __( 'Your email address will not be published.' ) . ( $req ? $required_text : '' ) . '</p>',
"fields" => array(
"author" => '<div class="comment-respond__item"><label class="comment-respond__label" for="author">' . __( 'Name', 'domainreference' ) . ( $req ? '<span class="comment-respond__required">*</span>' : '' ) . '</label>' . '<input class="comment-respond__input" id="author" name="author" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '" size="60" aria-required="true" /></div>',
"email" => '<div class="comment-respond__item"><label class="comment-respond__label" for="email">' . __( 'Email', 'domainreference' ) . ( $req ? '<span class="comment-respond__required">*</span>' : '' ) . '</label>' . '<input class="comment-respond__input" id="email" name="email" type="text" value="' . esc_attr( $commenter['comment_author_email'] ) . '" size="60" aria-required="true" /></div>',
"url" => '<div class="comment-respond__item"><label class="comment-respond__label" for="url">' . __( 'Website', 'domainreference' ) . '</label>' . '<input class="comment-respond__input" id="url" name="url" type="text" value="' . esc_attr( $commenter['comment_author_url'] ) . '" size="30" /></div>',
"cookies" => '<div class="comment-respond__item comment-respond__item--large"><input class="comment-respond__checkbox" id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes"/><label class="comment-respond__checkbox-label" for="wp-comment-cookies-consent">Save my name, email, and website in this browser for the next time I comment.</label></div>',
),
);
?>
<div class="comments" id="comments">
<div class="comments__head">
<h2 class="comments__title">
<?php
if (comments_open()) :
if (have_comments()) :
echo 'Join the conversation';
else:
echo 'Leave a comment';
endif;
else:
echo 'Comments are closed';
endif;
?>
</h2>
</div>
<div class="comments__body">
<ol class="comments__list">
<?php
wp_list_comments(array(
"walker" => new Windycoys_Walker_Comments(),
));
?>
</ol>
</div>
<div class="comments__foot">
<?php comment_form($form_settings) ?>
</div>
</div>

28
src/css/archive.css Normal file
View File

@@ -0,0 +1,28 @@
.archive__list {
margin-bottom: var(--space-sm);
}
.archive__list--sub-list {
margin-left: var(--space-sm);
}
.archive__heading,
.archive__subheading {
font-family: var(--heading-font-family);
color: var(--color-dark-blue);
margin-bottom: var(--space-xs);
}
.archive__heading {
font-size: var(--size-heading-2);
}
.archive__subheading {
font-size: var(--size-heading-3);
}
.archive__date {
display: inline-block;
font-style: italic;
min-width: 2.25rem;
}

27
src/css/article.css Normal file
View File

@@ -0,0 +1,27 @@
@media (--viewport-lg) {
.article {
border-bottom: 1px solid var(--color-light-grey);
}
}
.article__date {
color: var(--color-grey);
margin-bottom: var(--space-sm);
}
@media (--viewport-lg) {
.article__date {
display: none;
}
}
.article__date-icon {
vertical-align: middle;
}
.article__date-text {
margin-left: var(--space-xxs);
vertical-align: middle;
font-style: oblique;
font-size: var(--size-body-small);
}

10
src/css/avatar.css Normal file
View File

@@ -0,0 +1,10 @@
.avatar {
position: absolute;
top: 0;
border-radius: var(--space-xxs);
transition: filter var(--transition-md) ease-out;
}
.avatar:hover {
filter: saturate(1.3) contrast(1.3);
}

60
src/css/base.css Normal file
View File

@@ -0,0 +1,60 @@
html {
box-sizing: border-box;
line-height: var(--base-line-height);
font-size: var(--base-font-size);
}
body {
background-color: #fff;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3E%3Cpath fill='%23e0e0e0' fill-opacity='0.55' d='M1 3h1v1H1V3zm2-2h1v1H3V1z'%3E%3C/path%3E%3C/svg%3E");
color: var(--color-near-black);
font-family: var(--body-font-family);
margin: 0;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
blockquote,
dl,
dd,
h1,
h2,
h3,
h4,
h5,
h6,
figure,
table,
p,
pre {
margin: 0;
}
ol,
ul {
list-style: none;
margin: 0;
padding: 0;
}
img {
height: auto;
max-width: 100%;
user-select: none;
vertical-align: middle;
}
a,
a:active,
a:focus,
a:hover,
a:visited {
color: var(--color-near-black);
font-weight: 700;
outline: none;
text-decoration: none;
}

View File

@@ -0,0 +1,79 @@
.comment-respond__title {
border-bottom: 1px solid var(--color-light-grey);
margin-bottom: var(--space-xs);
padding-bottom: var(--space-sm);
}
.comment-respond__title-text {
margin-right: var(--space-xs);
}
.comment-respond__text {
font-size: var(--size-body-small);
}
.comment-respond__notes {
font-size: var(--size-body-extra-small);
margin-bottom: var(--space-sm);
}
.comment-respond__item {
margin-bottom: var(--space-sm);
max-width: 20rem;
}
.comment-respond__item--large {
max-width: 40rem;
}
.comment-respond__cancel {
font-size: var(--size-body-extra-small);
}
.comment-respond__label {
display: block;
margin-bottom: var(--space-xs);
}
.comment-respond__input {
background-color: #fff;
border: 1px solid var(--color-near-black);
font-size: var(--size-body-small);
padding: var(--space-xs);
width: 100%;
}
.comment-respond__input:focus {
background-color: var(--color-pale-blue);
border-color: var(--color-light-blue);
outline: 0;
}
.comment-respond__submit {
background-color: var(--color-light-blue);
border: none;
color: #fff;
cursor: pointer;
font-family: var(--heading-font-family);
font-size: var(--size-body);
padding: var(--space-xs);
}
.comment-respond__cancel a,
.comment-respond__cancel a:visited {
color: var(--color-light-blue);
transition: box-shadow var(--transition-md) ease-out;
}
.comment-respond__cancel a:focus,
.comment-respond__cancel a:hover {
box-shadow: var(--link-focus);
}
.comment-respond__checkbox {
margin-right: var(--space-sm);
}
.comment-respond__checkbox-label {
font-size: var(--size-body-extra-small);
}

62
src/css/comment.css Normal file
View File

@@ -0,0 +1,62 @@
.comment {
margin-bottom: var(--space-sm);
}
.comment__head {
display: flex;
margin-bottom: var(--space-sm);
}
.comment__avatar {
margin-right: var(--space-sm);
padding-bottom: 100%;
width: var(--icon-size-xl);
}
.comment__metadata {
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
margin: var(--space-xs) 0;
}
.comment__date {
font-size: var(--size-body-extra-small);
font-style: oblique;
}
.comment__body {
margin-bottom: var(--space-sm);
}
.comment__reply.is-hidden {
display: none;
}
.comment__reply {
transition: color var(--transition-md) ease-out;
}
.comment__reply:focus,
.comment__reply:hover {
color: var(--color-light-blue);
}
.comment__reply-icon {
display: inline-block;
margin-right: var(--space-xs);
vertical-align: middle;
}
.comment__reply-text {
display: inline-block;
position: relative;
font-size: var(--size-body-extra-small);
vertical-align: middle;
transition: box-shadow var(--transition-md) ease-out;
}
.comment__reply:focus .comment__reply-text,
.comment__reply:hover .comment__reply-text {
box-shadow: var(--link-focus);
}

23
src/css/comments.css Normal file
View File

@@ -0,0 +1,23 @@
.comments {
border-bottom: 1px solid var(--color-light-grey);
padding-bottom: var(--space-md);
}
.comments__head {
margin-bottom: var(--space-md);
}
.comments__title {
margin-bottom: var(--space-sm);
}
.comments__list--sub-list .comments__item {
border-left: 2px solid var(--color-light-blue);
padding-left: var(--space-sm);
}
@media (--viewport-md) {
.comments__list--sub-list .comments__item {
padding-left: var(--space-md);
}
}

192
src/css/content.css Normal file
View File

@@ -0,0 +1,192 @@
.content h1,
.content h2,
.content h3,
.content h4,
.content h5,
.content h6 {
font-family: var(--heading-font-family);
margin-bottom: var(--space-sm);
color: var(--color-dark-blue);
}
.content h1 {
font-size: var(--size-heading-1);
}
.content h2 {
font-size: var(--size-heading-2);
}
.content h3 {
font-size: var(--size-heading-3);
}
.content h4 {
font-size: var(--size-heading-4);
}
.content h5 {
font-size: var(--size-heading-5);
}
.content h6 {
font-size: var(--size-heading-6);
}
.content p {
margin-bottom: var(--space-sm);
}
.content ul,
.content ol {
counter-reset: li;
margin-bottom: var(--space-sm);
}
.content ul li,
.content ol li {
counter-increment: li;
position: relative;
margin-bottom: var(--space-xs);
padding-left: var(--space-md);
}
.content ul li:before,
.content ol li:before {
position: absolute;
left: 0;
}
.content ul li:before {
content: "";
top: calc(var(--base-line-height) / 2 * 1rem);
background-color: var(--color-light-blue);
width: var(--bullet-size);
height: var(--bullet-size);
border-radius: 50%;
transform: translateY(-50%);
}
.content ol li:before {
content: counter(li) ".";
top: 0;
color: var(--color-light-blue);
font-weight: 700;
font-size: 0.9rem;
}
.content a {
color: var(--color-light-blue);
transition: box-shadow var(--transition-md) ease-out;
}
.content a img {
transition: box-shadow var(--transition-md) ease-out,
filter var(--transition-md) ease-out;
}
.content a:focus {
box-shadow: var(--link-focus);
}
.content a:focus img {
box-shadow: var(--image-focus);
filter: brightness(125%);
}
.content a:hover {
box-shadow: var(--link-focus);
}
/**
* Wordpress overrides
*/
.content .twitter-tweet {
width: auto !important;
margin: 0 auto;
}
.content .wp-caption {
background-color: #fff;
border: 1px solid var(--color-light-grey);
border-radius: var(--space-xxs);
display: inline-block;
margin: 0 0 var(--space-sm);
padding: var(--space-sm);
width: auto !important;
}
.content .wp-caption a {
display: inline-block;
}
.content .wp-caption a:after {
display: none;
}
@media (--viewport-md) {
.content .twitter-tweet,
.content .wp-caption {
padding: var(--space-sm) var(--space-md);
}
}
.content .wp-caption-text {
font-family: var(--heading-font-family);
margin: var(--space-sm) 0 0;
}
.content .wp-block-quote {
border-left: var(--space-xxs) solid var(--color-light-blue);
margin-bottom: var(--space-sm);
padding: var(--space-sm) var(--space-md);
}
.content .wp-block-quote cite {
font-size: 0.8rem;
}
.content .wp-block-table {
display: flex;
flex-direction: column;
align-items: center;
}
.content figcaption {
font-size: var(--size-body-extra-small);
font-style: italic;
text-align: center;
color: var(--color-dark-blue);
}
.content table {
border-collapse: collapse;
table-layout: fixed;
display: block;
overflow-x: auto;
height: auto !important;
max-width: 85vw;
white-space: nowrap;
margin-bottom: var(--space-md);
width: auto !important;
}
@media (--viewport-md) {
.content table {
max-width: 100%;
}
}
.content td {
border: 1px solid var(--color-dark-blue);
padding: var(--space-xs);
}
.content th {
border-width: 0 0 2px;
}
.content iframe {
max-width: 100%;
}

104
src/css/excerpt.css Normal file
View File

@@ -0,0 +1,104 @@
.excerpt {
display: flex;
flex-flow: column nowrap;
flex-grow: 1;
border-bottom: 1px solid var(--color-light-grey);
margin-bottom: var(--space-md);
}
.excerpt__head,
.excerpt__body {
margin-bottom: var(--space-xs);
}
.excerpt__body {
flex-grow: 1;
}
@media (--viewport-md) {
.excerpt__head,
.excerpt__body {
margin-bottom: var(--space-sm);
}
}
.excerpt__title {
font-size: var(--size-heading-6);
}
.excerpt__list {
color: var(--color-grey);
font-size: var(--size-body-extra-small);
margin-bottom: var(--space-sm);
}
.excerpt__list-item {
display: inline-block;
margin-bottom: var(--space-xs);
}
.excerpt__icon,
.excerpt__text {
font-weight: 100;
vertical-align: top;
}
.excerpt__text {
font-style: oblique;
margin: 0 var(--space-sm) 0 var(--space-xxs);
}
.excerpt__audio {
margin-bottom: var(--space-sm);
width: 18rem;
height: 3rem;
}
.excerpt__image {
height: 12rem;
margin-bottom: var(--space-sm);
}
.excerpt__links {
font-size: var(--size-body-extra-small);
margin-bottom: var(--space-sm);
}
.excerpt__link {
display: inline;
}
.excerpt__link:not(:last-child) {
position: relative;
margin-right: var(--space-xs);
padding-right: var(--space-xs);
}
.excerpt__link:not(:last-child):after {
content: "";
position: absolute;
top: 2px;
bottom: 2px;
right: 0;
width: 0.1rem;
background-color: var(--color-light-blue);
}
.excerpt__list-link {
color: inherit;
transition: color var(--transition-md) ease-out;
}
.excerpt__list-link:visited {
color: inherit;
}
.excerpt__list-link:hover,
.excerpt__list-link:focus {
color: var(--color-light-blue);
}
.excerpt__list-link:hover .excerpt__text,
.excerpt__list-link:focus .excerpt__text {
box-shadow: var(--link-focus);
}

9
src/css/footer.css Normal file
View File

@@ -0,0 +1,9 @@
.footer {
text-align: center;
font-size: var(--size-body-extra-small);
}
.footer__head,
.footer__body {
margin-bottom: var(--space-sm);
}

42
src/css/icon.css Normal file
View File

@@ -0,0 +1,42 @@
.icon {
display: inline-block;
height: var(--icon-size-md);
width: var(--icon-size-md);
}
.icon--extra-extra-small {
height: var(--icon-size-xxs);
width: var(--icon-size-xxs);
}
.icon--extra-small {
height: var(--icon-size-xs);
width: var(--icon-size-xs);
}
.icon--small {
height: var(--icon-size-sm);
width: var(--icon-size-sm);
}
.icon--large {
height: var(--icon-size-lg);
width: var(--icon-size-lg);
}
.icon--extra-large {
height: var(--icon-size-xl);
width: var(--icon-size-xl);
}
.icon--facebook {
color: var(--color-facebook);
}
.icon--twitter {
color: var(--color-twitter);
}
.icon--rss {
color: var(--color-rss);
}

80
src/css/index.css Normal file
View File

@@ -0,0 +1,80 @@
@import "base";
@import "archive";
@import "article";
@import "avatar";
@import "comment-respond";
@import "comment";
@import "comments";
@import "content";
@import "excerpt";
@import "footer";
@import "icon";
@import "link";
@import "logo";
@import "menu";
@import "metadata";
@import "nav";
@import "page";
@import "pagination";
@import "search";
@import "silhouette";
@import "social";
@import "title";
body {
--space-xxs: 0.25rem;
--space-xs: 0.5rem;
--space-sm: 1rem;
--space-md: 2rem;
--space-lg: 4rem;
--base-line-height: 1.625;
--base-font-size: 1.125rem;
--size-heading-1: 2rem;
--size-heading-2: 1.8rem;
--size-heading-3: 1.6rem;
--size-heading-4: 1.424rem;
--size-heading-5: 1.267rem;
--size-heading-6: 1.125rem;
--size-body: 1rem;
--size-body-small: 0.889rem;
--size-body-extra-small: 0.79rem;
--logo-size-sm: 7rem;
--logo-size-md: 9rem;
--logo-size-lg: 10rem;
--logo-size-xl: 12rem;
--icon-size-xxs: 0.7rem;
--icon-size-xs: 1rem;
--icon-size-sm: 1.5rem;
--icon-size-md: 2rem;
--icon-size-lg: 2.5rem;
--icon-size-xl: 4rem;
--menu-size: 3rem;
--menu-size-xl: 4rem;
--transition-fs: 0.15s;
--transition-md: 0.3s;
--transition-sl: 0.6s;
--heading-font-family: "Raleway", sans-serif;
--body-font-family: "Open Sans", sans-serif;
}
.theme-light {
--color-black: #000;
--color-near-black: #333;
--color-dark-blue: #201f42;
--color-light-blue: #1574d2;
--color-pale-blue: #e9f4ff;
--color-grey: #757575;
--color-light-grey: #e0e0e0;
--color-facebook: #3e5a98;
--color-twitter: #1da1f2;
--color-rss: #ee802f;
--link-focus: 0 0.1rem 0 0 var(--color-light-blue);
--image-focus: 0 0 0 0.2rem #fff, 0 0 0 0.4rem var(--color-light-blue);
--bullet-size: 0.45rem;
}
@custom-media --viewport-sm (min-width: 30em);
@custom-media --viewport-md (min-width: 40em);
@custom-media --viewport-lg (min-width: 60em);
@custom-media --viewport-xl (min-width: 75em);
@custom-media --viewport-wordpress-admin-bar (min-width: 783px);

12
src/css/link.css Normal file
View File

@@ -0,0 +1,12 @@
.link,
.link:hover,
.link:focus,
.link:visited {
color: var(--color-light-blue);
transition: box-shadow var(--transition-md) ease-out;
}
.link:focus,
.link:hover {
box-shadow: var(--link-focus);
}

45
src/css/logo.css Normal file
View File

@@ -0,0 +1,45 @@
.logo {
width: 100%;
}
@media (--viewport-lg) and (min-height: 34rem) {
.is-fixed .logo {
position: fixed;
width: var(--logo-size-lg);
z-index: 10;
}
}
@media (--viewport-xl) and (min-height: 34rem) {
.is-fixed .logo {
width: var(--logo-size-xl);
}
}
.logo__link {
display: block;
position: relative;
margin: 0 auto;
max-width: 16rem;
border-radius: 50%;
transition: box-shadow var(--transition-fs) ease-out;
padding-bottom: 100%;
}
.logo__link:focus {
box-shadow: var(--image-focus);
}
.logo__link:before {
filter: drop-shadow(0.2rem 0.2rem 0.2rem rgba(0, 0, 0, 0.5));
}
.logo__image {
bottom: 0;
display: block;
left: 0;
position: absolute;
right: 0;
top: 0;
transition: opacity var(--transition-sl) ease-out;
}

86
src/css/menu.css Normal file
View File

@@ -0,0 +1,86 @@
.menu {
background-color: var(--color-dark-blue);
border-radius: 50%;
box-shadow: 0.1rem 0.1rem 0.1rem rgba(0, 0, 0, 0.25);
cursor: pointer;
display: block;
height: var(--menu-size);
left: var(--space-xxs);
position: fixed;
top: var(--space-xxs);
opacity: 0;
transition: filter var(--transition-md) ease-out,
opacity var(--transition-md) ease-out,
transform var(--transition-md) ease-out;
width: var(--menu-size);
will-change: opacity, transition;
z-index: 5;
}
@media (--viewport-xl) {
.menu {
height: var(--menu-size-xl);
width: var(--menu-size-xl);
left: 1vw;
top: 1vw;
}
}
.logged-in .menu {
top: calc(var(--space-xxs) + 48px);
}
@media (--viewport-wordpress-admin-bar) {
.logged-in .menu {
top: calc(var(--space-xxs) + 34px);
}
}
.menu__line {
background-color: #fff;
border-radius: 4%;
height: 4%;
left: 25%;
position: absolute;
right: 25%;
transform: translateY(-50%);
}
.menu__line:nth-of-type(1) {
top: 33.34%;
}
.menu__line:nth-of-type(2) {
top: 50%;
}
.menu__line:nth-of-type(3) {
top: 66.67%;
}
.menu__text {
left: -10000px;
position: absolute;
top: -10000px;
}
.menu.is-visible {
opacity: 1;
}
.menu.is-minimized {
opacity: 0.5;
transform: translate(calc(var(--space-sm) * -1), calc(var(--space-sm) * -1));
}
/**
* Hover and focus states
*/
.menu:focus,
.menu:hover {
outline: none;
opacity: 1;
filter: saturate(1.5) contrast(1.5);
transform: scale(1.1);
}

90
src/css/metadata.css Normal file
View File

@@ -0,0 +1,90 @@
.metadata {
font-size: var(--size-body-extra-small);
border-bottom: 1px solid var(--color-light-grey);
}
@media (--viewport-lg) {
.metadata {
border-bottom: none;
}
}
@media (--viewport-lg) and (min-height: 34rem) {
.is-fixed .metadata {
position: fixed;
}
}
.metadata__list {
display: flex;
flex-flow: row wrap;
}
@media (--viewport-lg) {
.metadata__list {
flex-flow: column wrap;
}
}
.metadata__list-item {
display: flex;
align-items: center;
margin: 0 var(--space-sm) var(--space-sm) 0;
}
@media (--viewport-lg) {
.metadata__list-item {
margin-right: 0;
}
}
.metadata__list-item--light {
color: var(--color-grey);
display: none;
margin-bottom: var(--space-sm);
}
@media (--viewport-lg) {
.metadata__list-item--light {
display: block;
}
}
.metadata__icon {
display: inline-block;
vertical-align: middle;
}
.metadata__text {
font-style: oblique;
margin-left: var(--space-xs);
text-transform: capitalize;
transition: box-shadow var(--transition-md) ease-out;
vertical-align: middle;
}
.metadata__link {
display: inline-block;
transition: color var(--transition-md) ease-out;
}
.metadata__link:hover,
.metadata__link:focus {
color: var(--color-light-blue);
}
.metadata__link:hover .metadata__text,
.metadata__link:focus .metadata__text {
box-shadow: var(--link-focus);
}
.metadata__tag-link {
transition: box-shadow var(--transition-md) ease-out,
color var(--transition-md) ease-out;
}
.metadata__tag-link:hover,
.metadata__tag-link:focus {
color: var(--color-light-blue);
box-shadow: var(--link-focus);
}

194
src/css/nav.css Normal file
View File

@@ -0,0 +1,194 @@
:root {
--nav-transition-duration: var(--transition-md);
}
.nav:after {
background-color: rgba(0, 0, 0, 0.5);
bottom: 0;
content: "";
left: 0;
opacity: 0;
position: fixed;
right: 0;
transition: opacity var(--nav-transition-duration) ease-out,
visibility var(--nav-transition-duration) ease-out;
top: 0;
visibility: hidden;
z-index: 5;
}
.nav.is-open:after {
visibility: visible;
opacity: 1;
}
.nav__content {
background-color: var(--color-dark-blue);
bottom: 0;
box-shadow: 0.25rem 0 0.25rem rgba(0, 0, 0, 0.25);
color: #fff;
display: flex;
flex-direction: column;
left: 0;
padding: var(--space-sm);
position: fixed;
top: 0;
transform: translateX(-110%);
transition: transform var(--nav-transition-duration) ease-out;
z-index: 10;
overflow-y: auto;
}
.logged-in .nav__content {
top: 46px;
}
@media (--viewport-wordpress-admin-bar) {
.logged-in .nav__content {
top: 32px;
}
}
.nav__body {
flex-grow: 1;
}
.nav__title-link {
display: inline-block;
position: relative;
width: var(--icon-size-xl);
height: var(--icon-size-xl);
border-radius: 50%;
transition: box-shadow var(--transition-fs) ease-out;
}
.nav__title-link,
.nav__title-link:hover,
.nav__title-link:focus,
.nav__title-link:visited {
color: #fff;
}
.nav__title-link:focus {
box-shadow: 0 0 0 0.1rem var(--color-dark-blue), 0 0 0 0.2rem #fff;
}
.nav__title-link-image {
position: absolute;
top: 0;
left: 0;
}
.nav__close {
background-color: transparent;
border: none;
cursor: pointer;
display: block;
height: var(--icon-size-sm);
padding: 0;
position: absolute;
right: var(--space-sm);
top: var(--space-sm);
transition: box-shadow var(--nav-transition-duration) ease-out,
filter var(--nav-transition-duration) ease-out;
width: var(--icon-size-sm);
}
.nav__close:focus {
box-shadow: 0 0.1rem 0 0 #fff;
outline: 0;
}
.nav__close:hover {
filter: drop-shadow(0 0 0.1rem #fff);
}
.nav__close-bar {
background-color: #fff;
border-radius: 8%;
height: 8%;
position: absolute;
left: 0;
transition: transform var(--nav-transition-duration) ease-out
var(--nav-transition-duration);
transform: translateY(-50%);
top: 50%;
width: 100%;
}
.nav__close-text {
left: -10000px;
position: absolute;
}
/**
* nav List
*/
.nav__list {
font-family: var(--heading-font-family);
font-size: var(--size-heading-6);
}
.nav__list .nav__list {
margin-left: var(--space-sm);
}
.nav__link,
.nav__link:active,
.nav__link:focus,
.nav__link:hover,
.nav__link:visited {
color: #fff;
display: inline-block;
margin-bottom: var(--space-xs);
transition: box-shadow var(--nav-transition-duration) ease-out,
text-shadow var(--nav-transition-duration) ease-out;
}
.nav__link:hover {
text-shadow: 0 0 0.1rem #fff;
}
.nav__link:focus {
box-shadow: 0 0.1rem 0 0 #fff;
}
/**
* nav Social
*/
.nav__social {
margin-bottom: var(--space-xs);
}
.nav__social-link,
.nav__social-link:active,
.nav__social-link:focus,
.nav__social-link:hover,
.nav__social-link:visited {
display: inline-block;
color: #fff;
transition: box-shadow var(--nav-transition-duration) ease-out,
filter var(--nav-transition-duration) ease-out;
}
.nav__social-link:focus {
box-shadow: 0 0.1rem 0 0 #fff;
}
.nav__social-link:hover {
filter: drop-shadow(0 0 0.1rem #fff);
}
.nav.is-open .nav__content {
transform: translateX(0);
}
.nav.is-open .nav__close-bar:nth-of-type(1) {
transform: translateY(-50%) rotate(45deg);
}
.nav.is-open .nav__close-bar:nth-of-type(2) {
transform: translateY(-50%) rotate(-45deg);
}

118
src/css/page.css Normal file
View File

@@ -0,0 +1,118 @@
.page {
display: grid;
grid-auto-flow: dense;
grid-gap: var(--space-sm);
grid-template-columns: 1fr;
max-width: 60rem;
margin: var(--space-xs) var(--space-xs) 0;
}
.page__logo {
display: flex;
font-size: 0;
justify-content: center;
}
.page__banner {
display: none;
position: relative;
}
.page__pagination {
display: flex;
justify-content: center;
}
.page__content--centered-md {
text-align: center;
}
@media (--viewport-sm) {
.page {
grid-template-columns: var(--logo-size-sm) 1fr;
grid-template-rows: var(--logo-size-sm) 1fr;
grid-auto-rows: auto;
margin: var(--space-sm) var(--space-sm) 0;
}
.page__banner {
display: block;
grid-column: 2 / -1;
grid-row-start: 1;
}
.page__content,
.page__article,
.page__comments,
.page__metadata,
.page__pagination,
.page__footer {
grid-column: 1 / -1;
}
}
@media (--viewport-md) {
.page {
grid-template-columns: var(--logo-size-md) 1fr;
grid-template-rows: var(--logo-size-md) 1fr;
grid-gap: var(--space-md);
margin: var(--space-md) var(--space-md) 0;
}
.page__content,
.page__article.is-first {
grid-row: 2 / span 2;
}
.page__content--centered-md {
text-align: left;
}
}
@media (--viewport-lg) {
.page {
grid-template-columns: var(--logo-size-lg) 1fr;
grid-template-rows:
var(--icon-size-md) calc(var(--logo-size-lg) - var(--space-md) - 32px)
1fr;
}
.page__logo {
grid-row: span 2;
}
.page__content,
.page__article,
.page__comments {
grid-column: 2 / -1;
}
.page__metadata {
grid-column: 1;
}
}
@media (--viewport-xl) {
.page {
grid-template-columns: var(--logo-size-xl) 1fr;
grid-template-rows:
var(--icon-size-md) calc(
var(--logo-size-xl) - var(--space-md) - var(--icon-size-md)
)
1fr;
margin: var(--space-md) auto 0;
}
.page__columns {
display: flex;
flex-flow: row wrap;
margin: 0 calc(var(--space-md) / 2 * -1);
}
.page__cell {
display: flex;
flex-flow: column nowrap;
flex: 1 0 50%;
padding: 0 calc(var(--space-md) / 2);
}
}

40
src/css/pagination.css Normal file
View File

@@ -0,0 +1,40 @@
.pagination {
display: flex;
flex-flow: row wrap;
}
.pagination__list {
display: flex;
}
.pagination__item {
display: flex;
justify-content: center;
align-items: flex-end;
padding: 0 var(--space-xs);
}
.pagination__dots {
display: flex;
color: var(--color-light-blue);
}
.pagination__current {
font-weight: 700;
position: relative;
box-shadow: var(--link-focus);
}
.pagination__link,
.pagination__link:hover,
.pagination__link:focus,
.pagination__link:visited {
display: block;
color: var(--color-light-blue);
transition: transform var(--transition-md) ease-out;
}
.pagination__link:focus,
.pagination__link:hover {
transform: scale(1.3);
}

27
src/css/search.css Normal file
View File

@@ -0,0 +1,27 @@
.search {
display: flex;
}
.search__label {
left: -10000px;
position: absolute;
}
.search__input {
border: none;
border-radius: 0;
color: var(--color-near-black);
font-family: var(--heading-font-family);
font-size: var(--size-body-small);
max-width: 8rem;
padding: var(--space-xs);
}
.search__submit {
background-color: var(--color-light-blue);
border: none;
color: #fff;
font-family: var(--heading-font-family);
font-size: var(--size-body-small);
min-width: 5rem;
}

15
src/css/silhouette.css Normal file

File diff suppressed because one or more lines are too long

39
src/css/social.css Normal file
View File

@@ -0,0 +1,39 @@
.social {
display: flex;
justify-content: flex-end;
align-items: center;
}
.social__item {
margin-left: var(--space-xs);
}
.social__link {
display: block;
background-color: transparent;
border: 0;
padding: 0;
transition: filter var(--transition-fs) ease-out,
transform var(--transition-fs) ease-out;
transform-origin: center bottom;
}
.social__link:focus,
.social__link:hover {
filter: saturate(1.5) contrast(1.5);
transform: scale(1.1);
}
/* Donate button */
.social__item input[type="image"] {
transition: filter var(--transition-fs) ease-out,
transform var(--transition-fs) ease-out;
transform-origin: center bottom;
}
.social__item input[type="image"]:focus,
.social__item input[type="image"]:hover {
filter: saturate(1.5) contrast(1.5);
transform: scale(1.1);
}

0
src/css/theme.css Normal file
View File

20
src/css/title.css Normal file
View File

@@ -0,0 +1,20 @@
.title {
font-family: var(--heading-font-family);
color: var(--color-dark-blue);
font-size: var(--size-heading-1);
margin-bottom: var(--space-sm);
}
.title a {
color: inherit;
}
.title__icon,
.title__text {
display: inline-block;
vertical-align: middle;
}
.title__text {
text-transform: capitalize;
}

35
src/footer.php Normal file
View File

@@ -0,0 +1,35 @@
<?php
$js_url = get_template_directory_uri() . '/bundle.js';
$deploy_timestamp = windycoys_get_deploy_timestamp();
if ($deploy_timestamp) {
$js_url .= '?t=' . $deploy_timestamp;
}
?>
<div id="fb-root"></div>
<script type="text/javascript" src="<?php echo $js_url ?>"></script>
<script type="text/javascript">
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = 'https://connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v3.2';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
<script type="text/javascript">
window.twttr = (function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0],
t = window.twttr || {};
if (d.getElementById(id)) return t;
js = d.createElement(s);
js.id = id;
js.src = "https://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
t._e = [];
t.ready = function(f) {
t._e.push(f);
};
return t;
}(document, "script", "twitter-wjs"));</script>
</body>
</html>

58
src/front-page.php Normal file
View File

@@ -0,0 +1,58 @@
<?php get_header() ?>
<main class="page">
<section class="page__logo is-fixed">
<?php get_template_part('partials/logo') ?>
</section>
<section class="page__content page__content--centered-md">
<h1 class="title">Latest articles</h1>
<div class="page__columns">
<?php
$posts = get_posts(array(
"numberposts" => 4,
));
foreach ($posts as $post) {
$date = strtotime($post->post_date);
$year = date('Y', $date);
$month = date('F', $date);
$day = date('jS', $date);
$date = get_the_date(get_option('date_format'), $post->ID).' at '.get_the_date(get_option('time_format'), $post->ID);
$content = (strlen($post->post_excerpt) === 0) ?
strip_tags(substr($post->post_content, 0, 200)).' [...]' :
$post->post_excerpt;
$words = count(explode(" ", $post->post_content));
$excerpt = array(
"title" => $post->post_title,
"url" => get_permalink($post->ID),
"content" => $content,
"author" => get_the_author_meta('nickname', $post->post_author),
"comments" => $post->comment_count,
"words" => $words,
"date" => $date,
);
echo '<div class="page__cell">';
get_template_part('partials/excerpt');
echo '</div>';
}
?>
</div>
<h2 class="title">Podcasts</h2>
<div class="page__columns">
<div class="page__cell">
<?php $podcast = windycoys_get_podcast_meta('xin') ?>
<?php get_template_part('partials/podcast') ?>
</div>
<div class="page__cell">
<?php $podcast = windycoys_get_podcast_meta('tfc') ?>
<?php get_template_part('partials/podcast') ?>
</div>
</div>
</section>
<section class="page__banner">
<?php get_template_part('partials/banner') ?>
</section>
<section class="page__footer">
<?php get_template_part('partials/footer') ?>
</section>
</main>
<?php get_template_part('partials/navigation') ?>
<?php get_footer() ?>

196
src/functions.php Normal file
View File

@@ -0,0 +1,196 @@
<?php
function windycoys_the_tags() {
$tags = get_the_tags();
if (!$tags) return false;
// Suppress NewsNow tag
foreach($tags as $key=>$tag) {
if($tag->name === "newsnow") {
unset($tags[$key]);
}
}
if ($tags) {
foreach($tags as $key=>$tag) {
echo '<a class="metadata__tag-link" href="' .
home_url() . '/tag/' . $tag->name . '" rel="tag">' .
$tag->name . '</a>';
if ($key < count($tags) - 1) {
echo ', ';
}
}
}
}
function windycoys_get_twitter_share_url() {
$url = 'https://twitter.com/intent/tweet?text=';
$title = get_the_title();
$link = get_the_permalink();
return $url . urlencode($title . ' : ' . $link);
}
function windycoys_search_posts_per_page($query) {
if ($query->is_search) {
$query->set( 'posts_per_page', '10' );
}
return $query;
}
add_filter('pre_get_posts', 'windycoys_search_posts_per_page');
function windycoys_get_deploy_timestamp() {
if (file_exists(__DIR__ . '/.timestamp')) {
$timestamp = file_get_contents(__DIR__ . '/.timestamp');
return $timestamp;
}
return false;
}
function windycoys_create_podcasts_table() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE windycoys_podcasts (
id int(2) NOT NULL AUTO_INCREMENT,
podcast_id varchar(3) DEFAULT '' NOT NULL,
last_update bigint(10) DEFAULT 0 NOT NULL,
content longtext DEFAULT '' NOT NULL,
PRIMARY KEY (id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
$wpdb->insert('windycoys_podcasts', array(
'podcast_id' => 'tfc',
'last_update' => 0,
'content' => '{}'
));
$wpdb->insert('windycoys_podcasts', array(
'podcast_id' => 'xin',
'last_update' => 0,
'content' => '{}'
));
}
function windycoys_fetch_podcast_meta($id) {
global $wpdb;
$urls = array(
"tfc" => 'https://rss.acast.com/thefightingcock',
"xin" => 'https://rss.acast.com/theextrainch',
);
$feed = file_get_contents($urls[$id]);
$feed = str_replace('<media:', '<', $feed);
$feed = str_replace('</media:', '</', $feed);
$feed = str_replace('<itunes:', '<', $feed);
$feed = str_replace('</itunes:', '</', $feed);
$now = time();
$wpdb->update("windycoys_podcasts",
array('last_update' => $now, 'content' => $feed),
array('podcast_id'=>$id)
);
return $feed;
}
function windycoys_refresh_podcast_meta($id) {
global $wpdb;
$now = time();
$res = $wpdb->get_row('SELECT * FROM windycoys_podcasts WHERE
podcast_id = "' . $id .'"');
if (!$res) {
windycoys_create_podcasts_table();
}
if ($res->last_update + 300 < $now) {
return array(
"from_cache" => false,
"data" => windycoys_fetch_podcast_meta($id),
);
}
return array(
"from_cache" => true,
"data" => $res->content,
);
}
function windycoys_get_episodes_url($id) {
$urls = array(
"tfc" => 'https://play.acast.com/s/thefightingcock',
"xin" => 'https://play.acast.com/s/theextrainch',
);
return $urls[$id];
}
function windycoys_get_podcast_meta($id) {
$res = windycoys_refresh_podcast_meta($id);
$rss = simplexml_load_string($res['data']);
$item = $rss->channel->item;
$date = strtotime((String) $item->pubDate);
return array(
"id" => $id,
"from_cache" => $res['from_cache'],
"podcast_title" => (String) $rss->channel->title,
"podcast_description" => (String) $rss->channel->description,
"podcast_episodes" => windycoys_get_episodes_url($id),
"artwork_url" => (String) $rss->channel->image->url,
"title" => (String) $item->title,
"description" => (String) $item->description,
"image" => (String) $item->image['href'],
"date" => date(get_option('date_format'), $date).' at '.date(get_option('time_format'), $date),
"length" => (String) $item->duration,
"url" => (String) $item->link,
"audio" => (String) $item->enclosure['url'],
);
}
function windycoys_get_read_time($words) {
$wpm = 250;
$mins = ceil($words / $wpm);
return $mins;
}
function windycoys_is_ie() {
$ua = htmlentities($_SERVER["HTTP_USER_AGENT"], ENT_QUOTES, "UTF-8");
if (preg_match("~MSIE|Internet Explorer~i", $ua) || (strpos($ua, "Trident/7.0") !== false && strpos($ua, "rv:11.0") !== false)) {
return true;
}
return false;
}
function windycoys_first_sentence($string) {
$sentence = preg_split( '/(\.|!|\?)\s/', $string, 2, PREG_SPLIT_DELIM_CAPTURE );
return $sentence['0'] . $sentence['1'];
}
function windycoys_get_description($post_id) {
if (get_post_type() == "post") {
$post = get_post($post_id);
$content = (strlen($post->post_excerpt) === 0) ?
strip_tags(windycoys_first_sentence($post->post_content)) :
$post->post_excerpt;
return $content;
} else {
return get_bloginfo('description');
}
}
function windycoys_jetpack_custom_image($media, $post_id, $args) {
if ($media) {
return $media;
} else {
$url = get_template_directory_uri() . '/images/icon.png';
$permalink = get_permalink($post_id);
return array(
array(
"type" => 'image',
"from" => 'custom_fallback',
"src" => esc_url($url),
"href" => $permalink,
)
);
}
}
add_filter('jetpack_images_get_images', 'windycoys_jetpack_custom_image', 10, 3);
function windycoys_strip_scripts(&$scripts) {
if(!is_admin()){
$scripts->remove('jquery');
}
}
add_filter('wp_default_scripts', 'windycoys_strip_scripts');

27
src/header.php Normal file
View File

@@ -0,0 +1,27 @@
<?php
$css_url = get_template_directory_uri() . '/style.css';
$deploy_timestamp = windycoys_get_deploy_timestamp();
if ($deploy_timestamp) {
$css_url .= '?t=' . $deploy_timestamp;
}
$manifest = get_template_directory_uri() . '/manifest.json';
?>
<!doctype html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo('charset'); ?>">
<title><?php wp_title(''); ?><?php if(wp_title('', false)) { echo ' &laquo; '; } ?> <?php bloginfo('name'); ?></title>
<meta name="description" content="<?php echo windycoys_get_description(get_the_id()) ?>">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#201f42">
<?php wp_head(); ?>
<link rel="me" href="https://twitter.com/WindyCOYS">
<link rel="icon" type="image/png" href="<?php echo get_template_directory_uri() ?>/images/icon_48.png">
<link rel="manifest" href="<?php echo $manifest ?>">
<link rel="stylesheet" href="<?php echo $css_url ?>">
<link href="//fonts.googleapis.com/css?family=Open+Sans|Raleway:700" rel="stylesheet">
<?php if (windycoys_is_ie()) : ?>
<style type="text/css">.is-fixed .logo,.is-fixed .metadata{position: static;}</style>
<?php endif; ?>
</head>
<body class="theme-light">

47
src/icons.php Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/images/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
src/images/icon_144.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

BIN
src/images/icon_168.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

BIN
src/images/icon_192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

BIN
src/images/icon_48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
src/images/icon_512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
src/images/icon_72.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
src/images/icon_96.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
src/images/logo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

BIN
src/images/newsnow_sw.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

BIN
src/images/tfc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
src/images/xin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 KiB

1
src/index.css Normal file
View File

@@ -0,0 +1 @@
@import "./css/index";

44
src/index.php Normal file
View File

@@ -0,0 +1,44 @@
<?php get_header() ?>
<main class="page">
<section class="page__logo">
<?php get_template_part('partials/logo') ?>
</section>
<?php $index = 0; while ( have_posts() ) : the_post(); $index++; ?>
<section class="page__article<?php echo ($index === 1 ? ' is-first' : '') ?>">
<article class="article">
<div class="article__date">
<svg class="icon icon--extra-small">
<use href="#icon-calendar"></use>
</svg>
<span class="article__date-text">
<?php the_time(get_option('date_format')) ?>
</span>
</div>
<div class="article__content">
<h1 class="title">
<a href="<?php the_permalink(); ?>">
<?php the_title(); ?>
</a>
</h1>
<div class="content">
<?php the_content(__('Continue reading <span class="meta-nav">&raquo;</span>', 'windycoys')); ?>
</div>
</div>
</article>
</section>
<section class="page__metadata">
<?php get_template_part('partials/metadata') ?>
</section>
<?php endwhile; ?>
<section class="page__pagination">
<?php get_template_part('partials/pagination') ?>
</section>
<section class="page__banner">
<?php get_template_part('partials/banner') ?>
</section>
<section class="page__footer">
<?php get_template_part('partials/footer') ?>
</section>
</main>
<?php get_template_part('partials/navigation') ?>
<?php get_footer() ?>

22
src/index.ts Normal file
View File

@@ -0,0 +1,22 @@
import { App } from "./ts";
document.addEventListener("DOMContentLoaded", () => new App());
/*
import { Image, Menu, Navigation, ReplyToComment } from "./ts";
document.addEventListener("DOMContentLoaded", () => {
Array.from(document.querySelectorAll("img")).forEach((image) => {
new Image(image).start();
});
const menu = document.querySelector("#menu") as HTMLButtonElement;
const navigation = document.querySelector(".nav") as HTMLElement;
const form = document.querySelector("#respond") as HTMLDivElement;
const links = Array.from(
document.querySelectorAll(".comment__reply")
) as HTMLLinkElement[];
const btn = new Menu(document.querySelector("#menu"), window);
btn.init();
new Navigation(navigation, btn).init();
new ReplyToComment(form, links).init();
});
*/

47
src/manifest.json Normal file
View File

@@ -0,0 +1,47 @@
{
"name": "WindyCOYS",
"description": "Spurs Blog, often focussing on goal analysis & under 18/loan players",
"lang": "en-GB",
"start_url": ".",
"display": "standalone",
"background_color": "#fff",
"theme_color": "#201f42",
"icons": [
{
"src": "images/icon_48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "images/icon_72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "images/icon_96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "images/icon_144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "images/icon_168.png",
"sizes": "168x168",
"type": "image/png"
},
{
"src": "images/icon_192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "images/icon_512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}

25
src/page-archive.php Normal file
View File

@@ -0,0 +1,25 @@
<?php get_header(); the_post(); ?>
<main class="page">
<section class="page__logo is-fixed">
<?php get_template_part('partials/logo') ?>
</section>
<section class="page__content">
<h1 class="title">
<a href="<?php the_permalink(); ?>">
<?php the_title(); ?>
</a>
</h1>
<div class="content">
<?php the_content(); ?>
</div>
<?php get_template_part('partials/archive') ?>
</section>
<section class="page__banner">
<?php get_template_part('partials/banner') ?>
</section>
<section class="page__footer">
<?php get_template_part('partials/footer') ?>
</section>
</main>
<?php get_template_part('partials/navigation') ?>
<?php get_footer() ?>

30
src/page.php Normal file
View File

@@ -0,0 +1,30 @@
<?php get_header(); ?>
<main class="page">
<section class="page__logo">
<?php get_template_part('partials/logo') ?>
</section>
<?php if (have_posts()): while (have_posts()) : the_post(); ?>
<section class="page__content">
<h1 class="title">
<?php the_title(); ?>
</h1>
<div class="content">
<?php the_content(); ?>
</div>
</section>
<?php endwhile; ?>
<?php else: ?>
<section class="page__content">
<h1 class="title">Sorry, there is no article to display</h1>
<a class="link" href="<?php echo get_site_url() ?>/">Go back home</a>
</section>
<?php endif; ?>
<section class="page__banner">
<?php get_template_part('partials/banner') ?>
</section>
<section class="page__footer">
<?php get_template_part('partials/footer') ?>
</section>
</main>
<?php get_template_part('partials/navigation') ?>
<?php get_footer() ?>

62
src/partials/archive.php Normal file
View File

@@ -0,0 +1,62 @@
<?php
$posts = get_posts(array(
"numberposts" => -1,
"order" => 'ASC',
));
$archive = array();
foreach ($posts as $post) {
$date = strtotime($post->post_date);
$year = date('Y', $date);
$month = date('F', $date);
$day = date('jS', $date);
$url = get_permalink($post->ID);
$comments = $post->comment_count === '1' ? '1 comment' : $post->comment_count . ' comments';
if ($post->post_status === 'publish') {
$archive[$year][$month][] = array(
"title" => $post->post_title,
"slug" => $post->post_name,
"author" => $post->post_author,
"day" => $day,
"url" => $url,
"comments" => $comments,
);
}
}
?>
<div class="archive">
<ol class="archive__list">
<?php foreach ($archive as $year => $yearData) : ?>
<li class="archive__item">
<h2 class="archive__heading">
<?php echo $year ?>
</h2>
<ol class="archive__list archive__list--sub-list">
<?php foreach ($yearData as $month => $monthData) : ?>
<li class="archive__item">
<h3 class="archive__subheading">
<?php echo $month ?>
</h3>
<ol class="archive__list archive__list--sub-list">
<?php foreach ($monthData as $post) : ?>
<li class="archive__item">
<span class="archive__date">
<?php echo $post['day'] ?>
</span>
<a class="link" href="<?php echo $post['url'] ?>">
<?php echo $post['title'] ?>
</a>
<span class="archive__comments">
(<?php echo $post['comments'] ?>)
</span>
</li>
<?php endforeach; ?>
</ol>
</li>
<?php endforeach; ?>
</ol>
</li>
<?php endforeach; ?>
</ol>
</div>

26
src/partials/banner.php Normal file
View File

@@ -0,0 +1,26 @@
<div class="social">
<div class="social__item">
<a class="social__link" href="https://www.facebook.com/WindyCOYS/" aria-label="WindyCOYS on Facebook">
<svg class="icon icon--facebook" aria-hidden="true">
<use href="#icon-facebook"></use>
</svg>
</a>
</div>
<div class="social__item">
<a class="social__link" href="https://twitter.com/windycoys/" aria-label="WindyCOYS on Twitter">
<svg class="icon icon--twitter" aria-hidden="true">
<use href="#icon-twitter"></use>
</svg>
</a>
</div>
<div class="social__item">
<a class="social__link" href="/feed" aria-label="WindyCOYS RSS Feed">
<svg class="icon icon--rss" aria-hidden="true">
<use href="#icon-rss"></use>
</svg>
</a>
</div>
<div class="social__item">
<?php echo do_shortcode('[paypal-donation]'); ?>
</div>
</div>

65
src/partials/excerpt.php Normal file
View File

@@ -0,0 +1,65 @@
<?php
global $excerpt;
?>
<div class="excerpt">
<div class="excerpt__head">
<div class="excerpt__title">
<a class="link" href="<?php echo $excerpt['url'] ?>">
<?php echo $excerpt['title'] ?>
</a>
</div>
</div>
<div class="excerpt__body">
<?php echo str_replace(
'[...]',
'<a class="link" href="' . $excerpt['url'] . '" aria-label="Read full article">'
. '<svg class="icon icon--extra-extra-small"><use href="#icon-arrow-double-right"></use></a>',
$excerpt['content']);
?>
</div>
<div class="excerpt__foot">
<ul class="excerpt__list">
<li class="excerpt__list-item">
<span class="excerpt__icon">
<svg class="icon icon--extra-small" aria-hidden="true">
<use href="#icon-profile"></use>
</svg>
</span>
<span class="excerpt__text"><?php echo $excerpt['author'] ?></span>
</li>
<?php if ($excerpt['words']) : ?>
<li class="excerpt__list-item">
<span class="excerpt__icon">
<svg class="icon icon--extra-small" aria-hidden="true">
<use href="#icon-clock"></use>
</svg>
</span>
<span class="excerpt__text"><?php echo windycoys_get_read_time($excerpt['words']) ?> minute read</span>
</li>
<?php endif; ?>
<li class="excerpt__list-item">
<span class="excerpt__icon">
<svg class="icon icon--extra-small" aria-hidden="true">
<use href="#icon-calendar"></use>
</svg>
</span>
<span class="excerpt__text"><?php echo $excerpt['date'] ?></span>
</li>
<li class="excerpt__list-item">
<a class="excerpt__list-link" href="<?php the_permalink() ?>#comments">
<span class="excerpt__icon">
<svg class="icon icon--extra-small" aria-hidden="true">
<use href="#icon-comments"></use>
</svg>
</span>
<span class="excerpt__text">
<?php
$number = $excerpt['comments'];
echo $number === '1' ? '1 comment' : $number . ' comments';
?>
</span>
</a>
</li>
</ul>
</div>
</div>

12
src/partials/footer.php Normal file
View File

@@ -0,0 +1,12 @@
<footer class="footer">
<div class="footer__head">
<p class="footer__text">&copy; <?php echo date('Y'); ?> <?php bloginfo('name'); ?></p>
</div>
<div class="footer__body">
<a href="https://www.newsnow.co.uk/h/Sport/Football/Premier+League/Tottenham+Hotspur" title="Click here for more Tottenham Hotspur news from NewsNow">
<img src="<?php echo get_template_directory_uri() ?>/images/newsnow_sw.gif" alt="As featured on NewsNow: Tottenham Hotspur news">
</a>
</div>
<?php get_template_part('icons') ?>
</footer>
<?php wp_footer() ?>

6
src/partials/logo.php Normal file
View File

@@ -0,0 +1,6 @@
<div class="logo">
<a class="logo__link has-silhouette" href="<?php echo home_url(); ?>">
<img src="<?php echo get_template_directory_uri(); ?>/images/icon.png" alt="WindyCOYS logo" class="logo__image">
</a>
</div>

76
src/partials/metadata.php Normal file
View File

@@ -0,0 +1,76 @@
<section class="metadata">
<ul class="metadata__list">
<li class="metadata__list-item metadata__list-item--light">
<span class="metadata__icon">
<svg class="icon icon--small" aria-hidden="true">
<use href="#icon-calendar"></use>
</svg>
</span>
<span class="metadata__text">
<?php the_time(get_option('date_format')) ?>
</span>
</li>
<?php if (is_user_logged_in()): ?>
<li class="metadata__list-item">
<a class="metadata__link" href="<?php echo get_edit_post_link() ?>">
<span class="metadata__icon">
<svg class="icon icon--small" aria-hidden="true">
<use href="#icon-edit"></use>
</svg>
</span>
<span class="metadata__text">
Edit post
</span>
</a>
</li>
<?php endif; ?>
<li class="metadata__list-item">
<a class="metadata__link" href="<?php the_permalink() ?>#comments">
<span class="metadata__icon">
<svg class="icon icon--small" aria-hidden="true">
<use href="#icon-comments"></use>
</svg>
</span>
<span class="metadata__text">
<?php comments_number(); ?>
</span>
</a>
</li>
<li class="metadata__list-item">
<span class="metadata__icon">
<svg class="icon icon--small" aria-hidden="true">
<use href="#icon-tag"></use>
</svg>
</span>
<span class="metadata__text">
<?php windycoys_the_tags() ?>
</span>
</div>
<li class="metadata__list-item">
<div
class="fb-share-button"
data-href="<?php echo get_the_permalink() ?>"
data-layout="box_count"
data-size="small"
data-mobile-iframe="false"
>
<a
target="_blank"
href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fdevelopers.facebook.com%2Fdocs%2Fplugins%2F&amp;src=sdkpreparse"
class="fb-xfbml-parse-ignore"
>
Share
</a>
</div>
</li>
<li class="metadata__list-item">
<a
class="twitter-share-button"
href="<?php echo windycoys_get_twitter_share_url() ?>"
data-url="<?php echo get_the_permalink() ?>"
>
Tweet
</a>
</li>
</ul>
</section>

View File

@@ -0,0 +1,64 @@
<?php
require get_template_directory() . '/classes/walker.navigation.php';
$menu = wp_nav_menu(array(
'echo' => false,
'menu' => 'navigation',
'container_class' => 'nav__menu',
'menu_class' => 'nav__list',
'walker' => new Windycoys_Walker_Navigation(),
));
$menu = str_replace(
'ul id="menu-navigation" class="nav__list"',
'ul id="menu-navigation" class="nav__list" role="menubar"',
$menu
);
?>
<button class="menu" id="menu">
<span class="menu__line"></span>
<span class="menu__line"></span>
<span class="menu__line"></span>
<span class="menu__text">Open menu</span>
</button>
<nav class="nav<?php echo is_user_logged_in() ? ' logged-in' : '' ?>" aria-label="Main Navigation">
<div class="nav__content">
<div class="nav__head">
<h2 class="nav__title">
<a class="nav__title-link" href="<?php get_site_url() ?>/" aria-label="Back Home" tabindex="-1">
<span class="nav__title-link-icon">
<svg class="icon icon--extra-large">
<use href="#icon-windy"></use>
</svg>
</span>
<img src="<?php echo get_template_directory_uri(); ?>/images/icon.png" alt="WindyCOYS logo" class="nav__title-link-image" data-load-transition="false">
</a>
</h2>
</div>
<div class="nav__body">
<?php echo $menu ?>
</div>
<div class="nav__foot">
<div class="nav__social">
<a class="nav__social-link" href="https://www.facebook.com/WindyCOYS/" aria-label="WindyCOYS on Facebook">
<svg class="icon icon--large">
<use href="#icon-facebook"></use>
</svg>
</a>
<a class="nav__social-link" href="https://twitter.com/windycoys/" aria-label="WindyCOYS on Twitter">
<svg class="icon icon--large">
<use href="#icon-twitter"></use>
</svg>
</a>
</div>
<div class="nav__search">
<?php get_search_form() ?>
</div>
<button class="nav__close">
<span class="nav__close-bar"></span>
<span class="nav__close-bar"></span>
<span class="nav__close-text">Close menu</span>
</button>
</div>
</div>
</nav>

View File

@@ -0,0 +1,76 @@
<?php
global $wp;
$url = home_url($wp->request);
$base_url = substr($url, 0, strpos($url, "page/"));
$current = get_query_var('paged');
$total = $wp_query->max_num_pages;
$links = paginate_links(array(
"type" => 'array',
"prev_next" => false,
"current" => $current,
"end_size" => 2,
));
function get_previous_url($base_url, $page) {
$qs = $_SERVER['QUERY_STRING'];
$url = $base_url . 'page/' . ($page - 1);
if ($qs) {
$url .= '/?' . $qs;
}
return $url;
}
function get_next_url($base_url, $page) {
$qs = $_SERVER['QUERY_STRING'];
$url = $base_url . 'page/';
if ($page === 0) {
$url .= '2';
} else {
$url .= ($page + 1);
}
if ($qs) {
$url .= '/?' . $qs;
}
return $url;
}
function format_link($link) {
if (strpos($link, 'page-numbers dots')) {
return '<span class="pagination__dots"><svg class="icon icon--extra-small"><use href="#icon-ellipsis"></use></svg></span>';
}
$link = str_replace('page-numbers current', 'pagination__current', $link);
$link = str_replace('page-numbers', 'link', $link);
return $link;
}
if (count($links) > 1) :
?>
<div class="pagination">
<?php if ($current > 1) : ?>
<div class="pagination__previous">
<a class="pagination__link" href="<?php echo get_previous_url($base_url, $current) ?>" aria-label="Previous page">
<svg class="icon icon--small">
<use href="#icon-chevron-left"></use>
</svg>
</a>
</div>
<?php endif; ?>
<nav class="pagination__content" role="navigation" aria-label="Pagination navigation">
<ul class="pagination__list">
<?php foreach($links as $link) { ?>
<li class="pagination__item">
<?php echo format_link($link) ?>
</li>
<?php } ?>
</ul>
</nav>
<?php if ($current < $total) : ?>
<div class="pagination__next">
<a class="pagination__link" href="<?php echo get_next_url($base_url, $current) ?>" aria-label="Next page">
<svg class="icon icon--small">
<use href="#icon-chevron-right"></use>
</svg>
</a>
</div>
<?php endif; ?>
</div>
<?php endif; ?>

50
src/partials/podcast.php Normal file
View File

@@ -0,0 +1,50 @@
<?php
global $podcast;
$artwork = get_template_directory_uri().'/images/'.$podcast['id'].'.png';
?>
<div class="excerpt">
<div class="excerpt__head">
<img
class="excerpt__image"
title="<?php echo $podcast['podcast_title'] ?>"
src="<?php echo $artwork ?>">
<h3 class="excerpt__title">
<a class="link" href="<?php echo $podcast['url'] ?>">
<?php echo $podcast['title'] ?>
</a>
</h3>
</div>
<div class="excerpt__body">
<?php echo $podcast['description'] ?>
</div>
<div class="excerpt__foot">
<audio class="excerpt__audio" src="<?php echo $podcast['audio'] ?>" controls="true">
Your browser does not support the <code>audio</code> element.
</audio>
<ul class="excerpt__links">
<li class="excerpt__link">
<a
class="link"
href="<?php echo $podcast['audio'] ?>"
title="Download the MP3">
Download MP3
</a>
</li>
<li class="excerpt__link">
<a class="link" href="<?php echo $podcast['podcast_episodes'] ?>">
More episodes
</a>
</li>
</ul>
<ul class="excerpt__list">
<li class="excerpt__list-item">
<span class="excerpt__icon">
<svg class="icon icon--extra-small" aria-hidden="true">
<use href="#icon-calendar"></use>
</svg>
</span>
<span class="excerpt__text"><?php echo $podcast['date'] ?></span>
</li>
</ul>
</div>
</div>

52
src/search.php Normal file
View File

@@ -0,0 +1,52 @@
<?php
global $wp_query;
get_header();
$query = $_GET['s'];
$results = $wp_query->found_posts;
?>
<main class="page">
<section class="page__logo is-fixed">
<?php get_template_part('partials/logo') ?>
</section>
<section class="page__content">
<?php if ($results === 0) : ?>
<h1 class="title">Sorry, no results found.</h1>
<a class="link" href="<?php echo get_site_url() ?>/">Go back home</a>
<?php else : ?>
<h1 class="title">
<?php
echo $results.' result'.($results !== '1' ? 's' : '').' matching "' . $query . '" found.';
?>
</h1>
<?php endif; ?>
<ol>
<?php if (have_posts()): while (have_posts()) : the_post(); ?>
<li>
<?php
$excerpt = array(
"title" => get_the_title(),
"url" => get_the_permalink(),
"content" => get_the_excerpt(),
"author" => get_the_author_meta('nickname'),
"comments" => get_comments_number(),
"date" => get_the_date(get_option('date_format'), $id) . ' at ' . get_the_date(get_option('time_format'), $id),
"words" => count(explode(" ", $post->post_content)),
);
get_template_part('partials/excerpt')
?>
</li>
<?php endwhile; endif; ?>
</ol>
</section>
<section class="page__pagination">
<?php get_template_part('partials/pagination') ?>
</section>
<section class="page__banner">
<?php get_template_part('partials/banner') ?>
</section>
<section class="page__footer">
<?php get_template_part('partials/footer') ?>
</section>
</main>
<?php get_template_part('partials/navigation') ?>
<?php get_footer() ?>

9
src/searchform.php Normal file
View File

@@ -0,0 +1,9 @@
<form id="searchform" role="search" method="get" action="<?php echo get_site_url()?>">
<div class="search">
<label class="search__label" for="searchinput">
Search
</label>
<input id="searchinput" class="search__input" name="s" type="text" placeholder="Search">
<input id="searchsubmit" class="search__submit" value="Search" type="submit">
</div>
</form>

50
src/single.php Normal file
View File

@@ -0,0 +1,50 @@
<?php get_header(); ?>
<main class="page">
<section class="page__logo is-fixed">
<?php get_template_part('partials/logo') ?>
</section>
<?php if (have_posts()): while (have_posts()) : the_post(); ?>
<section class="page__article is-first">
<article class="article">
<div class="article__date">
<span class="article__date-icon">
<svg class="icon icon--extra-small">
<use href="#icon-calendar"></use>
</svg>
</span>
<span class="article__date-text">
<?php the_time(get_option('date_format')) ?>
</span>
</div>
<div class="article__content">
<h1 class="title">
<?php the_title(); ?>
</h1>
<div class="content">
<?php the_content(__('Continue reading <span class="meta-nav">&raquo;</span>', 'windycoys')); ?>
</div>
</div>
</article>
</section>
<section class="page__metadata is-fixed">
<?php get_template_part('partials/metadata') ?>
</section>
<section class="page__comments">
<?php comments_template() ?>
</section>
<?php endwhile; ?>
<?php else: ?>
<section class="page__content">
<h1 class="title">Sorry, there is no article to display</h1>
<a class="link" href="<?php echo get_site_url() ?>/">Go back home</a>
</section>
<?php endif; ?>
<section class="page__banner">
<?php get_template_part('partials/banner') ?>
</section>
<section class="page__footer">
<?php get_template_part('partials/footer') ?>
</section>
</main>
<?php get_template_part('partials/navigation') ?>
<?php get_footer() ?>

53
src/tag.php Normal file
View File

@@ -0,0 +1,53 @@
<?php get_header() ?>
<main class="page">
<section class="page__logo is-fixed">
<?php get_template_part('partials/logo') ?>
</section>
<section class="page__content">
<h1 class="title">
<span class="title__icon">
<svg class="icon" aria-hidden="true">
<use href="#icon-tag"></use>
</svg>
</span>
<span class="title__text">
<?php echo single_tag_title() ?>
</span>
</h1>
<ol>
<?php if (have_posts()): while (have_posts()) : the_post(); ?>
<li>
<?php
$excerpt = array(
"title" => get_the_title(),
"url" => get_the_permalink(),
"content" => get_the_excerpt(),
"author" => get_the_author_meta('nickname'),
"comments" => get_comments_number(),
"date" => get_the_date(get_option('date_format'), $id) . ' at ' . get_the_date(get_option('time_format'), $id),
"words" => count(explode(" ", $post->post_content)),
);
get_template_part('partials/excerpt');
?>
</li>
<?php endwhile; ?>
</ol>
</section>
<section class="page__pagination">
<?php get_template_part('partials/pagination') ?>
</section>
<?php else: ?>
<section class="page__content">
<h1 class="title">Sorry, no results found.</h1>
<a class="link" href="<?php echo get_site_url() ?>/">Go back home</a>
</section>
<?php endif; ?>
<section class="page__banner">
<?php get_template_part('partials/banner') ?>
</section>
<section class="page__footer">
<?php get_template_part('partials/footer') ?>
</section>
</main>
<?php get_template_part('partials/navigation') ?>
<?php get_footer() ?>

75
src/ts/app.ts Normal file
View File

@@ -0,0 +1,75 @@
import { Image } from "./image";
import { Menu } from "./menu";
import { Navigation } from "./navigation";
import { ReplyToComment } from "./reply-to-comment";
export class App {
menu: Menu;
navigation: Navigation;
constructor() {
Array.from(document.querySelectorAll("img")).forEach((image) =>
new Image(image).start()
);
this.menu = new Menu(document.querySelector("#menu"), window);
this.navigation = new Navigation(document.querySelector(".nav"));
new ReplyToComment();
this.attachEvents();
this.attachKeyEvents();
}
attachEvents(): void {
const { menu, navigation } = this;
menu.btn.addEventListener("click", (e) => {
e.preventDefault();
this.showNav();
});
navigation.container.addEventListener("click", (e) => {
if (navigation.container === e.target) {
this.hideNav();
}
});
navigation.container
.querySelector(".nav__close")
.addEventListener("click", () => {
this.hideNav();
});
}
attachKeyEvents() {
const { navigation } = this;
const first = navigation.container.querySelector(
".nav__link"
) as HTMLElement;
const last = navigation.container.querySelector(
".nav__close"
) as HTMLElement;
navigation.container.addEventListener("keydown", (e) => {
if (e.code === "Escape") {
this.hideNav();
}
});
first.addEventListener("keydown", (e) => {
if (e.shiftKey && e.code === "Tab") {
e.preventDefault();
last.focus();
}
});
last.addEventListener("keydown", (e) => {
if (!e.shiftKey && e.code === "Tab") {
e.preventDefault();
first.focus();
}
});
}
showNav(): void {
this.menu.hide();
this.navigation.show();
}
hideNav(): void {
this.menu.show();
this.navigation.hide();
}
}

27
src/ts/image.ts Normal file
View File

@@ -0,0 +1,27 @@
export class Image {
image: HTMLImageElement;
constructor(img: HTMLImageElement) {
this.image = img;
}
fadeIn(): void {
this.image.style.opacity = "1";
}
attachEvents(): void {
this.image.addEventListener("load", () => this.fadeIn());
}
start(): void {
if (this.image.dataset.loadTransition === "false") {
return;
}
this.image.style.opacity = "0";
if (this.image.complete) {
this.fadeIn();
} else {
this.attachEvents();
}
}
}

1
src/ts/index.ts Normal file
View File

@@ -0,0 +1 @@
export * from "./app";

55
src/ts/menu.ts Normal file
View File

@@ -0,0 +1,55 @@
export class Menu {
window: Window;
btn: HTMLButtonElement;
state: "hidden" | "minimized" | "visible";
lastScrollPosition: number;
constructor(button: HTMLButtonElement, window: Window) {
this.btn = button;
this.window = window;
this.state = "visible";
this.lastScrollPosition = 0;
this.btn.setAttribute("aria-expanded", "false");
this.attachEvents();
setTimeout(() => {
this.show();
}, 1000);
}
attachEvents(): void {
this.window.addEventListener("scroll", () => {
this.updateState(this.lastScrollPosition, window.scrollY);
this.lastScrollPosition = window.scrollY;
});
}
updateState(lastY = 0, currentY: number): void {
if (this.state !== "hidden") {
if (this.state !== "visible" && currentY < lastY) {
this.show();
} else if (this.state !== "minimized" && currentY > lastY) {
this.minimize();
}
}
}
show(): void {
this.state = "visible";
this.btn.setAttribute("aria-expanded", "false");
this.btn.classList.remove("is-minimized");
this.btn.classList.add("is-visible");
}
minimize(): void {
this.state = "minimized";
this.btn.classList.remove("is-visible");
this.btn.classList.add("is-minimized");
}
hide(): void {
this.state = "hidden";
this.btn.setAttribute("aria-expanded", "true");
this.btn.classList.remove("is-visible");
this.btn.classList.remove("is-minimized");
}
}

26
src/ts/navigation.ts Normal file
View File

@@ -0,0 +1,26 @@
export class Navigation {
container: HTMLElement;
title: HTMLElement;
lastActiveElement: HTMLElement;
constructor(container: HTMLElement) {
this.container = container;
this.title = container.querySelector(".nav__title-link") as HTMLElement;
this.container.setAttribute("aria-hidden", "true");
}
show() {
this.lastActiveElement = document.activeElement as HTMLElement;
this.container.classList.add("is-open");
this.container.setAttribute("aria-hidden", "false");
this.title.focus();
}
hide() {
this.container.classList.remove("is-open");
this.container.setAttribute("aria-hidden", "true");
if (this.lastActiveElement) {
this.lastActiveElement.focus();
}
}
}

View File

@@ -0,0 +1,72 @@
export class ReplyToComment {
clonedForm: HTMLDivElement;
form: HTMLDivElement;
links: HTMLLinkElement[];
constructor() {
this.form = document.querySelector("#respond") as HTMLDivElement;
if (this.form) {
this.links = Array.from(
document.querySelectorAll(".comment__reply")
) as HTMLLinkElement[];
this.clonedForm = this.form.cloneNode(true) as HTMLDivElement;
if (this.links.length > 0) {
this.attachEvents();
}
}
}
attachEvents(): void {
this.links.forEach((link) => {
link.addEventListener("click", (e) => this.handleLinkClick(e, link));
});
}
handleLinkClick(e: Event, link: HTMLLinkElement): void {
e.preventDefault();
link.classList.add("is-hidden");
this.form.style.display = "none";
const targetNode = link.parentNode.querySelector(
".comment__inline-reply"
) as HTMLDivElement;
const { commentId, commentAuthor } = link.dataset;
this.insertForm(targetNode, commentId, commentAuthor);
}
insertForm(
targetNode: HTMLDivElement,
commentId: string,
commentAuthor: string
): void {
const clonedForm = this.clonedForm.cloneNode(true) as HTMLDivElement;
const cancel = clonedForm.querySelector(
"#cancel-comment-reply-link"
) as HTMLLinkElement;
const submit = clonedForm.querySelector("#submit") as HTMLInputElement;
const commentParent = clonedForm.querySelector(
"#comment_parent"
) as HTMLInputElement;
clonedForm.querySelector(
".comment-respond__title-text"
).innerHTML = `Reply to ${commentAuthor}`;
submit.value = "Post reply";
commentParent.value = commentId;
targetNode.appendChild(clonedForm);
cancel.style.display = "inline-block";
cancel.addEventListener("click", (e) =>
this.handleCancelClick(e, targetNode)
);
}
handleCancelClick(e: Event, container: HTMLDivElement) {
e.preventDefault();
container.parentNode
.querySelector(".comment__reply")
.classList.remove("is-hidden");
while (container.firstChild) {
container.removeChild(container.firstChild);
}
this.form.style.display = "block";
}
}