├── .gitignore ├── screenshot.png ├── library ├── missing.png ├── sass │ ├── base │ │ ├── elements │ │ │ ├── _body.scss │ │ │ ├── _tables.scss │ │ │ ├── _hr.scss │ │ │ ├── _lists.scss │ │ │ ├── _media.scss │ │ │ ├── _links.scss │ │ │ ├── _buttons.scss │ │ │ ├── _fields.scss │ │ │ ├── _darkmode.scss │ │ │ └── _icons.scss │ │ ├── typography │ │ │ ├── _typography.scss │ │ │ ├── _headings.scss │ │ │ └── _copy.scss │ │ └── _base.scss │ ├── admin.scss │ ├── abstracts │ │ ├── _abstracts.scss │ │ ├── variables │ │ │ ├── _columns.scss │ │ │ ├── _structure.scss │ │ │ ├── _typography.scss │ │ │ └── _colors.scss │ │ └── mixins │ │ │ └── _mixins.scss │ ├── generic │ │ ├── _box-sizing.scss │ │ └── _normalize.scss │ ├── components │ │ ├── media │ │ │ ├── _media.scss │ │ │ └── _captions.scss │ │ ├── _components.scss │ │ ├── widgets │ │ │ └── _widgets.scss │ │ ├── navigation │ │ │ ├── _page-headers.scss │ │ │ ├── _footer.scss │ │ │ ├── _misc.scss │ │ │ └── _header.scss │ │ ├── comments │ │ │ └── _comments.scss │ │ └── content │ │ │ ├── _snippets.scss │ │ │ └── _posts-and-pages.scss │ ├── plugins │ │ ├── jetpack │ │ │ └── _infinite-scroll.scss │ │ └── woocommerce │ │ │ └── _woocommerce.scss │ ├── utilities │ │ ├── _alignments.scss │ │ └── _accessibility.scss │ ├── editor.scss │ ├── layouts │ │ └── _layout.scss │ └── style.scss ├── icons │ ├── lifetheme-icons.ttf │ ├── lifetheme-icons.woff │ └── lifetheme-icons.woff2 ├── fonts │ └── inter │ │ ├── Inter-roman.var.woff2 │ │ └── Inter-italic.var.woff2 └── js │ ├── editor.js │ ├── customizer.js │ └── navigation.js ├── template-parts ├── thumbnail.php ├── card-landscape.php ├── content-none.php ├── content-page.php ├── card.php ├── content-attachment.php └── content.php ├── attachment.php ├── searchform.php ├── front-page.php ├── style.css ├── 404.php ├── inc ├── wpcom.php ├── custom-header.php ├── jetpack.php ├── customizer.php ├── bookmarks-meta.php ├── template-functions.php ├── woocommerce.php └── template-tags.php ├── page.php ├── search.php ├── theme.json ├── footer.php ├── index.php ├── archive-life_bookmark.php ├── single.php ├── comments.php ├── archive.php ├── header.php ├── phpcs.xml.dist ├── README.md ├── acf-export-2021-04-26.json ├── languages └── lifetheme.pot ├── LICENSE └── functions.php /.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache/ 2 | *.css.map 3 | css/ 4 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kangabell/lifetheme/HEAD/screenshot.png -------------------------------------------------------------------------------- /library/missing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kangabell/lifetheme/HEAD/library/missing.png -------------------------------------------------------------------------------- /library/sass/base/elements/_body.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background: var(--color__background-body); 3 | } 4 | -------------------------------------------------------------------------------- /library/sass/base/elements/_tables.scss: -------------------------------------------------------------------------------- 1 | table { 2 | margin: 0 0 1.5em; 3 | width: 100%; 4 | } 5 | -------------------------------------------------------------------------------- /library/icons/lifetheme-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kangabell/lifetheme/HEAD/library/icons/lifetheme-icons.ttf -------------------------------------------------------------------------------- /library/icons/lifetheme-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kangabell/lifetheme/HEAD/library/icons/lifetheme-icons.woff -------------------------------------------------------------------------------- /library/sass/admin.scss: -------------------------------------------------------------------------------- 1 | .column-img { 2 | width: 9rem; 3 | 4 | img { 5 | height: auto; 6 | width: 8rem; 7 | } 8 | } -------------------------------------------------------------------------------- /library/icons/lifetheme-icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kangabell/lifetheme/HEAD/library/icons/lifetheme-icons.woff2 -------------------------------------------------------------------------------- /library/fonts/inter/Inter-roman.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kangabell/lifetheme/HEAD/library/fonts/inter/Inter-roman.var.woff2 -------------------------------------------------------------------------------- /library/fonts/inter/Inter-italic.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kangabell/lifetheme/HEAD/library/fonts/inter/Inter-italic.var.woff2 -------------------------------------------------------------------------------- /library/sass/abstracts/_abstracts.scss: -------------------------------------------------------------------------------- 1 | @import "variables/colors"; 2 | @import "variables/typography"; 3 | @import "variables/structure"; 4 | @import "variables/columns"; 5 | @import "mixins/mixins"; 6 | -------------------------------------------------------------------------------- /library/sass/abstracts/variables/_columns.scss: -------------------------------------------------------------------------------- 1 | $columns: ( 2 | 1: 100%, 3 | 2: 50%, 4 | 3: 33.33%, 5 | 4: 25%, 6 | 5: 20%, 7 | 6: 16.66%, 8 | 7: 14.28%, 9 | 8: 12.5%, 10 | 9: 11.11% 11 | ); 12 | 13 | $columns__margin: 3.8%; 14 | -------------------------------------------------------------------------------- /library/sass/base/elements/_hr.scss: -------------------------------------------------------------------------------- 1 | hr { 2 | background-color: var(--color__background-hr); 3 | border: 0; 4 | height: 1px; 5 | margin-bottom: 1.5em; 6 | } 7 | 8 | .wp-block-separator { 9 | border: none; // reset 10 | width: 100%; // fixes unexplained invisibility at mobile sizes 11 | } -------------------------------------------------------------------------------- /library/sass/generic/_box-sizing.scss: -------------------------------------------------------------------------------- 1 | /* Inherit box-sizing to more easily change it's value on a component level. 2 | @link http://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/ */ 3 | *, 4 | *::before, 5 | *::after { 6 | box-sizing: inherit; 7 | } 8 | 9 | html { 10 | box-sizing: border-box; 11 | } 12 | -------------------------------------------------------------------------------- /library/sass/components/media/_media.scss: -------------------------------------------------------------------------------- 1 | .wp-block-image { 2 | margin-top: 2rem; 3 | margin-bottom: 2rem; 4 | 5 | &.aligncenter { 6 | width: 100%; 7 | } 8 | } 9 | 10 | .page-content .wp-smiley, 11 | .entry-content .wp-smiley, 12 | .comment-content .wp-smiley { 13 | border: none; 14 | margin-bottom: 0; 15 | margin-top: 0; 16 | padding: 0; 17 | } -------------------------------------------------------------------------------- /template-parts/thumbnail.php: -------------------------------------------------------------------------------- 1 | 2 | 7 | <?php esc_html__( 'Image Missing', 'life' ); ?> 8 | 11 | -------------------------------------------------------------------------------- /library/sass/plugins/jetpack/_infinite-scroll.scss: -------------------------------------------------------------------------------- 1 | /* Hide the Posts Navigation and the Footer when Infinite Scroll is in use. */ 2 | .infinite-scroll .posts-navigation, 3 | .infinite-scroll.neverending .site-footer { 4 | display: none; 5 | } 6 | 7 | /* Re-display the Theme Footer when Infinite Scroll has reached its end. */ 8 | .infinity-end.neverending .site-footer { 9 | display: block; 10 | } 11 | -------------------------------------------------------------------------------- /library/sass/base/elements/_lists.scss: -------------------------------------------------------------------------------- 1 | ul, 2 | ol { 3 | margin: 0; 4 | padding-left: 1.125rem; 5 | } 6 | 7 | ul { 8 | list-style: square; 9 | } 10 | 11 | ol { 12 | list-style: decimal; 13 | } 14 | 15 | .entry-content li { 16 | margin-bottom: 1rem; 17 | } 18 | 19 | li > ul, 20 | li > ol { 21 | margin-bottom: 0; 22 | margin-left: 1.5em; 23 | } 24 | 25 | dt { 26 | font-weight: 700; 27 | } 28 | 29 | dd { 30 | margin: 0 1.5em 1.5em; 31 | } 32 | -------------------------------------------------------------------------------- /library/sass/utilities/_alignments.scss: -------------------------------------------------------------------------------- 1 | .aligncenter { 2 | text-align: center; 3 | } 4 | 5 | @media screen and ($small-up) { 6 | 7 | .alignleft { 8 | 9 | /*rtl:ignore*/ 10 | float: left; 11 | 12 | /*rtl:ignore*/ 13 | margin-right: 1rem; 14 | margin-bottom: 1rem; 15 | } 16 | 17 | .alignright { 18 | 19 | /*rtl:ignore*/ 20 | float: right; 21 | 22 | /*rtl:ignore*/ 23 | margin-left: 1rem; 24 | margin-bottom: 1rem; 25 | } 26 | } -------------------------------------------------------------------------------- /library/sass/base/typography/_typography.scss: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 112.5%; // bump average base size from 16 to 18px 3 | -webkit-font-smoothing: antialiased; 4 | -moz-osx-font-smoothing: grayscale; 5 | } 6 | 7 | body, 8 | button, 9 | input, 10 | select, 11 | optgroup, 12 | textarea { 13 | color: var(--color__text-main); 14 | font-family: var(--font__main); 15 | font-size: 1rem; 16 | line-height: $font__line-height-body; 17 | } 18 | 19 | @import "headings"; 20 | @import "copy"; 21 | -------------------------------------------------------------------------------- /library/js/editor.js: -------------------------------------------------------------------------------- 1 | wp.domReady( () => { 2 | 3 | wp.blocks.registerBlockStyle( 'core/group', [ 4 | { 5 | name: 'default', 6 | label: 'Default', 7 | isDefault: true, 8 | }, 9 | { 10 | name: 'memo', 11 | label: 'Memo', 12 | } 13 | ]); 14 | 15 | wp.blocks.registerBlockStyle( 'core/heading', [ 16 | { 17 | name: 'default', 18 | label: 'Default', 19 | isDefault: true, 20 | }, 21 | { 22 | name: 'alt', 23 | label: 'Alternate', 24 | } 25 | ]); 26 | } ); -------------------------------------------------------------------------------- /library/sass/abstracts/variables/_structure.scss: -------------------------------------------------------------------------------- 1 | $size__site-main: 60rem; 2 | $size__site-narrow: 38rem; 3 | $size__site-wide: 72rem; 4 | $size__site-wider: 120rem; 5 | 6 | // breakpoints 7 | $small-down: 'max-width: 45.9rem'; 8 | $small-up: 'min-width: 30rem'; 9 | $medium-up: 'min-width: 46rem'; 10 | $large-up: 'min-width: 64rem'; 11 | $large-down: 'max-width: 87.9rem'; 12 | $xlarge-up: 'min-width: 88rem'; 13 | $xxlarge-up: 'min-width: 102rem'; 14 | 15 | $radius: 0.75rem; 16 | $radius-sm: 0.25rem; -------------------------------------------------------------------------------- /attachment.php: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | 15 | 23 | 24 |
25 | 26 | "> 2 | 3 | 4 | 8 | -------------------------------------------------------------------------------- /library/sass/editor.scss: -------------------------------------------------------------------------------- 1 | 2 | @import "abstracts/abstracts"; 3 | 4 | .editor-styles-wrapper { 5 | background-color: var(--color__background-body); 6 | font-family: $font__main; 7 | } 8 | 9 | .wp-block-group.is-style-memo { 10 | background-color: $white; 11 | border-radius: $radius; 12 | box-shadow: 0 0.25rem 1rem rgba($black, 0.1); 13 | font-family: $font__pre; 14 | padding: 2rem; 15 | } 16 | 17 | .wp-block-heading.is-style-alt { 18 | font-family: var(--font__alt); 19 | font-size: $typesize__small; 20 | letter-spacing: $font__letter-spacing; 21 | margin-bottom: 1rem; 22 | text-transform: uppercase; 23 | } 24 | -------------------------------------------------------------------------------- /front-page.php: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | 15 | 23 | 24 |
25 | 26 |
27 | 28 |
29 | 30 | 12 | 13 |
14 | 15 |
16 | 17 | 20 | 21 |
22 |

23 |
24 |
25 | 26 |
27 | 28 | 33 | h1, h2, h3, h4, h5, h6 { 34 | font-weight: bold; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /library/sass/base/elements/_buttons.scss: -------------------------------------------------------------------------------- 1 | button, 2 | input[type="button"], 3 | input[type="reset"], 4 | input[type="submit"] { 5 | @include button; 6 | transition: all 0.125s; 7 | } 8 | 9 | .icon-button { 10 | background: none; 11 | border: 0; 12 | font-weight: normal; 13 | 14 | &:hover { 15 | box-shadow: none; 16 | } 17 | } 18 | 19 | // note: default button block is "fill" style 20 | .wp-block-button__link { 21 | @include button($style: 'fill'); 22 | } 23 | 24 | // outline style has silver border 25 | .wp-block-button.is-style-outline > .wp-block-button__link { 26 | border-color: var(--color__border-button); 27 | color: var(--color__link); 28 | 29 | &:hover, 30 | &:focus { 31 | border-color: transparent; 32 | } 33 | } 34 | 35 | .wp-block-buttons .wp-block-button { 36 | display: inline-block; 37 | margin-right: 0.5rem; 38 | margin-bottom: 0.5rem; 39 | } -------------------------------------------------------------------------------- /inc/wpcom.php: -------------------------------------------------------------------------------- 1 | '', 24 | 'border' => '', 25 | 'text' => '', 26 | 'link' => '', 27 | 'url' => '', 28 | ); 29 | } 30 | } 31 | add_action( 'after_setup_theme', 'life_wpcom_setup' ); 32 | -------------------------------------------------------------------------------- /library/sass/plugins/woocommerce/_woocommerce.scss: -------------------------------------------------------------------------------- 1 | .woocommerce { 2 | 3 | span.onsale { 4 | font-family: var(--font__alt); 5 | font-size: $typesize__tiny; 6 | letter-spacing: $font__letter-spacing; 7 | text-transform: uppercase; 8 | z-index: 8; 9 | } 10 | 11 | a.button { 12 | @include button; 13 | font-weight: bold; 14 | transition: all 0.125s; 15 | } 16 | 17 | a.button.alt, 18 | button.button.alt { 19 | background-color: $mediumdark; 20 | font-weight: bold; 21 | 22 | &:hover, 23 | &:focus { 24 | background-color: $dark 25 | } 26 | } 27 | 28 | .woocommerce-breadcrumb { 29 | margin-top: 2rem; 30 | margin-bottom: 2rem; 31 | } 32 | 33 | .tabs > li > a { 34 | font-family: var(--font__alt); 35 | font-size: $typesize__small; 36 | font-weight: normal; 37 | letter-spacing: $font__letter-spacing; 38 | text-transform: uppercase; 39 | } 40 | } // .woocommerce -------------------------------------------------------------------------------- /page.php: -------------------------------------------------------------------------------- 1 | 17 | 18 |
19 | 20 | 33 | 34 |
35 | 36 | 12 | 13 |
14 | 15 | 16 | 17 | 24 | 25 |
26 | 36 |
37 | 38 | 48 | 49 |
50 | 51 | 10 | 11 |
12 | 13 |
14 | ', '' ); ?> 15 | ' . get_the_content() . '
'; 17 | 18 | $domain = str_ireplace('www.', '', parse_url($url, PHP_URL_HOST)); 19 | echo '

' . $domain . '

'; 20 | ?> 21 |
22 | 23 | 34 | <?php esc_html__( 'Image Missing', 'life' ); ?> 35 | 38 | -------------------------------------------------------------------------------- /theme.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "settings": { 4 | "color": { 5 | "defaultPalette": false, 6 | "palette": [ 7 | { 8 | "name": "Black", 9 | "slug": "black", 10 | "color": "#0d0d0d" 11 | }, 12 | { 13 | "name": "Grey", 14 | "slug": "grey", 15 | "color": "#aaaaaa" 16 | }, 17 | { 18 | "name": "Light", 19 | "slug": "light", 20 | "color": "#f7f7f7" 21 | }, 22 | { 23 | "name": "White", 24 | "slug": "white", 25 | "color": "#ffffff" 26 | }, 27 | { 28 | "name": "Purple", 29 | "slug": "purple", 30 | "color": "#9E23A5" 31 | }, 32 | { 33 | "name": "Red", 34 | "slug": "red", 35 | "color": "#C23F23" 36 | }, 37 | { 38 | "name": "Gold", 39 | "slug": "gold", 40 | "color": "#E4B83E" 41 | }, 42 | { 43 | "name": "Grass", 44 | "slug": "grass", 45 | "color": "#A0B438" 46 | }, 47 | { 48 | "name": "Teal", 49 | "slug": "teal", 50 | "color": "#4DA698" 51 | } 52 | ] 53 | }, 54 | "layout": { 55 | "contentSize": "60rem;", 56 | "wideSize": "72rem" 57 | }, 58 | "spacing": { 59 | "padding": true 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /footer.php: -------------------------------------------------------------------------------- 1 | 13 | 14 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /template-parts/content-none.php: -------------------------------------------------------------------------------- 1 | 11 | 12 |
13 | 16 | 17 |
18 | ' . wp_kses( 23 | /* translators: 1: link to WP admin new post page. */ 24 | __( 'Ready to publish your first post? Get started here.', 'life' ), 25 | array( 26 | 'a' => array( 27 | 'href' => array(), 28 | ), 29 | ) 30 | ) . '

', 31 | esc_url( admin_url( 'post-new.php' ) ) 32 | ); 33 | 34 | elseif ( is_search() ) : 35 | ?> 36 | 37 |

38 | 39 | 42 | 43 |

44 | 45 | 48 |
49 |
50 | -------------------------------------------------------------------------------- /library/sass/components/navigation/_page-headers.scss: -------------------------------------------------------------------------------- 1 | 2 | /*-------------------------------------------------------------- 3 | ## Page Header Title & Description 4 | --------------------------------------------------------------*/ 5 | 6 | .page-header { 7 | padding-top: 3rem; 8 | margin-bottom: 2rem; 9 | 10 | @media screen and ($large-up) { 11 | padding-top: 4rem; 12 | 13 | .page-title, 14 | p { 15 | margin-top: 0; 16 | } 17 | 18 | .page-title { 19 | margin-right: 2rem; 20 | } 21 | 22 | > .widget { 23 | align-items: baseline; 24 | display: flex; 25 | } 26 | 27 | .textwidget, 28 | .archive-description { 29 | flex: 1; 30 | } 31 | } 32 | } // .page-header 33 | 34 | 35 | /*-------------------------------------------------------------- 36 | ## Taxonomy Term Links Nav 37 | --------------------------------------------------------------*/ 38 | 39 | .page-header .menu { 40 | list-style: none; 41 | margin: 0; 42 | padding: 0; 43 | 44 | 45 | &-item { 46 | display: inline-block; 47 | 48 | a { 49 | @include button('tag'); 50 | } 51 | } 52 | 53 | .current-menu-item a { 54 | background: var(--color__background-alt); 55 | border-color: transparent; 56 | } 57 | 58 | @media screen and ($large-down) { 59 | display: flex; 60 | margin-right: -1rem; 61 | overflow-x: auto; 62 | padding-bottom: 0.5rem; 63 | scroll-behavior: smooth; 64 | -webkit-overflow-scrolling: touch; 65 | } 66 | } -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 17 | 18 |
19 | 20 | 25 | 30 | 54 | 55 |
56 | 57 | 11 | 12 |
> 13 | 14 | 17 | 18 |
19 | ', '' ); 22 | ?> 23 |
24 | 27 | 28 |
29 | '', 36 | ) 37 | ); 38 | ?> 39 |
40 | 41 | 42 | 62 | 63 |
64 | -------------------------------------------------------------------------------- /inc/custom-header.php: -------------------------------------------------------------------------------- 1 | 8 | * 9 | * @link https://developer.wordpress.org/themes/functionality/custom-headers/ 10 | * 11 | * @package Life 12 | */ 13 | 14 | if ( ! function_exists( 'life_header_style' ) ) : 15 | /** 16 | * Styles the header image and text displayed on the blog. 17 | * 18 | * @see life_custom_header_setup(). 19 | */ 20 | function life_header_style() { 21 | ?> 22 | 33 | 46 | 47 | 65 | 66 | 'life_bookmark', 14 | 'posts_per_page' => 60, // must be 60, but I'm not sure why 15 | 'paged' => $paged, 16 | ) ); 17 | 18 | $date_check = ''; 19 | 20 | get_header(); 21 | ?> 22 | 23 |
24 | 25 | have_posts() ) : ?> 26 | 27 | 33 | 34 |
35 | 36 | have_posts() ) : $query->the_post(); 38 | 39 | $date = get_the_date(); 40 | 41 | if ( $date != $date_check ) { 42 | echo '

' . $date . '

'; 43 | } 44 | 45 | get_template_part( 'template-parts/card-landscape' ); 46 | 47 | $date_check = $date; 48 | 49 | endwhile; 50 | ?> 51 | 52 |
53 | 54 | 66 | 67 |
68 | 69 |
70 | 71 |
72 | 73 | 12 | 13 |
14 | 15 | labels->name; 19 | 20 | the_post(); 21 | 22 | get_template_part( 'template-parts/content', get_post_type() ); 23 | 24 | // If comments are open or we have at least one comment, load up the comment template. 25 | if ( comments_open() || get_comments_number() ) : 26 | comments_template(); 27 | endif; 28 | 29 | if ( $post_type == 'post') : 30 | ?> 31 |
32 | 33 |
34 | '' . esc_html__( 'Older', 'life' ) . '' . '%title', 40 | 'next_text' => '' . esc_html__( 'Newer', 'life' ) . '' . '%title', 41 | ) 42 | ); 43 | 44 | echo ''; 45 | 46 | endwhile; // End of the loop. 47 | ?> 48 | 49 |
50 | 51 | 10 | 11 | > 12 | 23 | <?php esc_html__( 'Image Missing', 'life' ); ?> 24 | 27 | 28 |
29 | ', '' ); 31 | 32 | if ( 'life_bookmark' === get_post_type() ) : 33 | 34 | if (! is_front_page()) : 35 | $content = get_the_content(); 36 | $content_clean = preg_replace('#(.*?)#i', '\1', $content); 37 | echo '
' . $content_clean . '
'; 38 | endif; 39 | 40 | $domain = str_ireplace('www.', '', parse_url($url, PHP_URL_HOST)); 41 | echo '

' . $domain . '

'; 42 | 43 | elseif ( ('life_project' === get_post_type()) && (! is_singular('life_character')) && (! is_front_page()) ) : 44 | ?> 45 |
46 | ', '

'); 50 | 51 | endif; 52 | ?> 53 |
54 | -------------------------------------------------------------------------------- /template-parts/content-attachment.php: -------------------------------------------------------------------------------- 1 | 11 | 12 |
> 13 | 14 |
15 | 16 | 'post-thumbnail', 'size' => 'large', 'alt' => the_title_attribute(array('post'=>$attachment_id,'echo'=>0)) ) ); 24 | 25 | echo '
' . $attachment_image . '
'; 26 | 27 | the_title( '

', '

' ); 28 | 29 | echo '
' . get_the_content() . '
'; 30 | 31 | } else { 32 | 33 | the_title( '

', '

' ); 34 | 35 | the_content( 36 | sprintf( 37 | wp_kses( 38 | /* translators: %s: Name of current post. Only visible to screen readers */ 39 | __( 'Continue reading "%s"', 'life' ), 40 | array( 41 | 'span' => array( 42 | 'class' => array(), 43 | ), 44 | ) 45 | ), 46 | wp_kses_post( get_the_title() ) 47 | ) 48 | ); 49 | } 50 | 51 | wp_link_pages( 52 | array( 53 | 'before' => '', 55 | ) 56 | ); 57 | 58 | ?> 59 | 60 |
61 | 62 |
63 | -------------------------------------------------------------------------------- /inc/jetpack.php: -------------------------------------------------------------------------------- 1 | 'main', 23 | 'render' => 'life_infinite_scroll_render', 24 | 'footer' => 'page', 25 | ) 26 | ); 27 | 28 | // Add theme support for Responsive Videos. 29 | add_theme_support( 'jetpack-responsive-videos' ); 30 | 31 | // Add theme support for Content Options. 32 | add_theme_support( 33 | 'jetpack-content-options', 34 | array( 35 | 'post-details' => array( 36 | 'stylesheet' => 'life-style', 37 | 'date' => '.posted-on', 38 | 'categories' => '.cat-links', 39 | 'tags' => '.tags-links', 40 | 'author' => '.byline', 41 | 'comment' => '.comments-link', 42 | ), 43 | 'featured-images' => array( 44 | 'archive' => true, 45 | 'post' => true, 46 | 'page' => true, 47 | ), 48 | ) 49 | ); 50 | } 51 | add_action( 'after_setup_theme', 'life_jetpack_setup' ); 52 | 53 | if ( ! function_exists( 'life_infinite_scroll_render' ) ) : 54 | /** 55 | * Custom render function for Infinite Scroll. 56 | */ 57 | function life_infinite_scroll_render() { 58 | while ( have_posts() ) { 59 | the_post(); 60 | if ( is_search() ) : 61 | get_template_part( 'template-parts/content', 'search' ); 62 | else : 63 | get_template_part( 'template-parts/content', get_post_type() ); 64 | endif; 65 | } 66 | } 67 | endif; 68 | -------------------------------------------------------------------------------- /library/sass/components/comments/_comments.scss: -------------------------------------------------------------------------------- 1 | .comments-area { 2 | border-top: 1px solid var(--color__background-hr); 3 | padding-top: 2rem; 4 | margin-top: 2rem; 5 | } 6 | 7 | .comments-title { 8 | font-family: var(--font__alt); 9 | font-size: $typesize__h4; 10 | letter-spacing: $font__letter-spacing; 11 | margin-bottom: 2rem; 12 | text-align: center; 13 | text-transform: uppercase; 14 | } 15 | 16 | .comment-list { 17 | list-style: none; 18 | margin: 0 0 2rem; 19 | padding: 0; 20 | } 21 | 22 | .comment { 23 | border-bottom: 1px solid var(--color__background-hr); 24 | margin-bottom: 2rem; 25 | padding-bottom: 1rem; 26 | 27 | &-author { 28 | display: flex; 29 | flex-wrap: wrap; 30 | align-items: center; 31 | 32 | .avatar { 33 | border-radius: 50%; 34 | margin-right: 0.5rem; 35 | } 36 | 37 | .says { 38 | display: none; 39 | } 40 | } 41 | 42 | &-content { 43 | font-family: var(--font__alt); 44 | 45 | p { 46 | font-size: $typesize__small; 47 | } 48 | 49 | a { 50 | word-wrap: break-word; 51 | } 52 | } 53 | 54 | &-metadata { 55 | font-family: var(--font__alt); 56 | font-size: $typesize__tiny; 57 | letter-spacing: $font__letter-spacing; 58 | margin-top: 0.25rem; 59 | text-transform: uppercase; 60 | 61 | a { 62 | text-decoration: none; 63 | } 64 | } 65 | 66 | &-awaiting-moderation { 67 | display: block; 68 | font-size: $typesize__small; 69 | font-style: normal; 70 | font-weight: bold; 71 | margin: 0.5rem 0; 72 | } 73 | } // .comment 74 | 75 | .bypostauthor { 76 | display: block; 77 | } 78 | 79 | .comment-reply-title { 80 | font-size: $typesize__h6; 81 | } 82 | 83 | 84 | // all form inputs the same width 85 | .comment-form { 86 | 87 | input[type="text"], 88 | input[type="email"], 89 | input[type="url"], 90 | input[type="password"], 91 | textarea { 92 | width: 24rem; 93 | } 94 | } -------------------------------------------------------------------------------- /comments.php: -------------------------------------------------------------------------------- 1 | 22 | 23 |
24 | 25 | 29 | 30 |

31 | 32 | 33 | 34 |
    35 | true, 39 | ) 40 | ); 41 | ?> 42 |
43 | 44 | 50 |

51 |

'; // label removed for cleaner layout 57 | 58 | comment_form( array( 59 | 'comment_field' => $custom_comment_field, 60 | 'logged_in_as' => '', 61 | 'comment_notes_before' => '', 62 | 'title_reply_before' => '
', 63 | 'title_reply_after' => '', 64 | 'cancel_reply_after' => '
', 65 | 'label_submit' => esc_html__('Submit Reply', 'life') 66 | )); 67 | ?> 68 | 69 |
70 | -------------------------------------------------------------------------------- /library/sass/components/navigation/_footer.scss: -------------------------------------------------------------------------------- 1 | .site-footer { 2 | background: $dark; 3 | color: $medium; 4 | font-family: var(--font__alt); 5 | font-size: $typesize__small; 6 | padding-top: 3rem; 7 | padding-bottom: 4rem; 8 | 9 | a { 10 | color: $mediumlight; 11 | text-decoration-color: transparent; 12 | } 13 | 14 | .menu-item { 15 | margin-right: 1rem; 16 | margin-bottom: 1rem; 17 | 18 | a:hover, 19 | a:focus { 20 | text-decoration-color: $mediumdark; 21 | } 22 | } 23 | 24 | .menu-item.rss a::after { 25 | @include icon-style; 26 | content: $icon-rss; 27 | margin-left: 0.5em; 28 | vertical-align: -0.05em; 29 | } 30 | 31 | @media screen and ($medium-up) { 32 | 33 | .wrap { 34 | align-items: center; 35 | display: flex; 36 | flex-wrap: wrap; 37 | } 38 | 39 | .menu-item { 40 | margin-bottom: 0; 41 | } 42 | } 43 | } 44 | 45 | .footer-navigation .menu { 46 | display: flex; 47 | flex-wrap: wrap; 48 | list-style: none; 49 | margin: 0; 50 | padding-left: 0; 51 | } 52 | 53 | .site-info { 54 | font-size: $typesize__tiny; 55 | margin-top: 2rem; 56 | 57 | a { 58 | color: $medium; 59 | text-decoration-color: rgba($medium, 0.25); 60 | 61 | &:hover, 62 | &:focus { 63 | text-decoration-color: rgba($medium, 0.75); 64 | } 65 | } 66 | } 67 | 68 | .site-footer .buttons { 69 | align-items: center; 70 | display: flex; 71 | margin-left: auto; 72 | margin-top: 1rem; 73 | 74 | @media screen and ($medium-up) { 75 | margin-top: 0; 76 | } 77 | } 78 | 79 | .toggle-mode { 80 | background: $mediumdark; 81 | border: 0; 82 | border-radius: 2em; 83 | color: $light; 84 | display: inline-flex; 85 | margin-right: 1rem; 86 | padding: 0.175em 0.25em; 87 | 88 | &:hover, 89 | &:focus { 90 | box-shadow: none; 91 | } 92 | 93 | .icon-sun, 94 | .icon-moon { 95 | align-items: center; 96 | border-radius: 1rem; 97 | display: flex; 98 | height: 1.25em; 99 | justify-content: center; 100 | padding: 0.05em 0 0.025em; 101 | width: 1.25em; 102 | } 103 | 104 | .icon-sun { 105 | background: $dark; 106 | margin-right: 0.125rem; 107 | } 108 | 109 | .icon-moon { 110 | color: $black; 111 | } 112 | } -------------------------------------------------------------------------------- /library/sass/style.scss: -------------------------------------------------------------------------------- 1 | 2 | /*-------------------------------------------------------------- 3 | >>> TABLE OF CONTENTS: 4 | ---------------------------------------------------------------- 5 | # Generic 6 | - Normalize 7 | - Box sizing 8 | # Base 9 | - Typography 10 | - Elements 11 | - Links 12 | - Forms 13 | ## Layouts 14 | # Components 15 | - Navigation 16 | - Posts and pages 17 | - Comments 18 | - Widgets 19 | - Media 20 | - Captions 21 | - Galleries 22 | # plugins 23 | - Jetpack infinite scroll 24 | # Utilities 25 | - Accessibility 26 | - Alignments 27 | 28 | --------------------------------------------------------------*/ 29 | 30 | // Import variables and mixins. 31 | @import "abstracts/abstracts"; 32 | 33 | /*-------------------------------------------------------------- 34 | # Generic 35 | --------------------------------------------------------------*/ 36 | 37 | /* Normalize 38 | --------------------------------------------- */ 39 | @import "generic/normalize"; 40 | 41 | /* Box sizing 42 | --------------------------------------------- */ 43 | @import "generic/box-sizing"; 44 | 45 | /*-------------------------------------------------------------- 46 | # Base 47 | --------------------------------------------------------------*/ 48 | @import "base/base"; 49 | 50 | /*-------------------------------------------------------------- 51 | # Layouts 52 | --------------------------------------------------------------*/ 53 | @import "layouts/layout"; 54 | 55 | /*-------------------------------------------------------------- 56 | # Components 57 | --------------------------------------------------------------*/ 58 | @import "components/components"; 59 | 60 | /*-------------------------------------------------------------- 61 | # Plugins 62 | --------------------------------------------------------------*/ 63 | 64 | /* Jetpack infinite scroll 65 | --------------------------------------------- */ 66 | @import "plugins/jetpack/infinite-scroll"; 67 | 68 | /* WooCommerce 69 | --------------------------------------------- */ 70 | @import "plugins/woocommerce/woocommerce"; 71 | 72 | /*-------------------------------------------------------------- 73 | # Utilities 74 | --------------------------------------------------------------*/ 75 | 76 | /* Accessibility 77 | --------------------------------------------- */ 78 | @import "utilities/accessibility"; 79 | 80 | /* Alignments 81 | --------------------------------------------- */ 82 | @import "utilities/alignments"; 83 | -------------------------------------------------------------------------------- /library/sass/base/typography/_copy.scss: -------------------------------------------------------------------------------- 1 | p { 2 | margin-top: 1em; 3 | margin-bottom: 1.25em; 4 | } 5 | 6 | dfn, 7 | cite, 8 | em, 9 | i { 10 | font-style: italic; 11 | } 12 | 13 | cite { 14 | display: block; 15 | margin-top: 0.5em; 16 | } 17 | 18 | .wp-block-quote { 19 | border-left: 5px solid var(--color__background-hr); 20 | margin: 2rem 0; 21 | padding-left: 1rem; 22 | 23 | p { 24 | margin-bottom: 0; 25 | } 26 | } 27 | 28 | address { 29 | margin: 0 0 1.5em; 30 | } 31 | 32 | pre { 33 | background: var(--color__background-pre); 34 | font-family: $font__pre; 35 | line-height: $font__line-height-pre; 36 | margin-bottom: 1.6em; 37 | max-width: 100%; 38 | overflow: auto; 39 | padding: 1.6em; 40 | } 41 | 42 | code, 43 | kbd, 44 | tt, 45 | var { 46 | font-family: $font__code; 47 | } 48 | 49 | abbr, 50 | acronym { 51 | border-bottom: 1px dotted var(--color__border-abbr); 52 | cursor: help; 53 | } 54 | 55 | mark, 56 | ins { 57 | background: var(--color__background-ins); 58 | text-decoration: none; 59 | } 60 | 61 | big { 62 | font-size: 125%; 63 | } 64 | 65 | .has-huge-font-size, 66 | .has-larger-font-size { 67 | font-size: $typesize__large; 68 | 69 | @media screen and ($medium-up) { 70 | font-size: $typesize__huge; 71 | } 72 | } 73 | 74 | big, 75 | .has-large-font-size { 76 | font-size: $typesize__medium; 77 | 78 | @media screen and ($medium-up) { 79 | font-size: $typesize__huge; 80 | } 81 | } 82 | 83 | .has-medium-font-size { 84 | font-size: $typesize__medium; 85 | } 86 | 87 | .has-normal-font-size, 88 | .has-regular-font-size { 89 | } 90 | 91 | small, 92 | .has-small-font-size { 93 | font-size: $typesize__small; 94 | } 95 | 96 | .has-text-align-center { 97 | text-align: center; 98 | } 99 | 100 | .has-text-align-left { 101 | text-align: left; 102 | } 103 | 104 | .has-text-align-right { 105 | text-align: right; 106 | } 107 | 108 | .meta { 109 | color: var(--color__text-meta); 110 | font-family: $font__alt; 111 | font-size: $typesize__tiny; 112 | letter-spacing: $font__letter-spacing; 113 | margin-top: 0.5rem; 114 | margin-bottom: 0; 115 | text-transform: uppercase; 116 | } 117 | 118 | ::selection { 119 | background-color: $yellow; 120 | } 121 | 122 | .wp-block-group.is-style-memo { 123 | background-color: $white; 124 | border-radius: $radius; 125 | box-shadow: 0 0.25rem 1rem rgba($black, 0.1); 126 | color: $dark; 127 | font-family: $font__pre; 128 | padding: 2rem; 129 | } -------------------------------------------------------------------------------- /archive.php: -------------------------------------------------------------------------------- 1 | 20 | 21 |
22 | 23 | 24 | 25 | 42 | 43 |
44 | 45 | current_post ) && ( 0 === $wp_query->current_post % 15 ) ) : 57 | echo '
'; 58 | endif; 59 | 60 | get_template_part( 'template-parts/thumbnail' ); 61 | elseif ( is_tax( 'life_bookmark_type' ) ) : 62 | get_template_part( 'template-parts/card-landscape' ); 63 | else : 64 | get_template_part( 'template-parts/card' ); 65 | endif; 66 | 67 | endwhile; 68 | ?> 69 | 70 |
71 | 72 | 84 |
85 | 86 |
87 | 90 | 91 |
92 | 93 | section and everything up until
6 | * 7 | * @link https://developer.wordpress.org/themes/basics/template-files/#template-partials 8 | * 9 | * @package Life 10 | */ 11 | 12 | ?> 13 | 14 | > 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | > 24 | 25 |
26 | 27 | 28 | 96 | -------------------------------------------------------------------------------- /library/sass/abstracts/variables/_colors.scss: -------------------------------------------------------------------------------- 1 | $black: #0d0d0d; 2 | $dark: #191919; 3 | $mediumdark: #525252; 4 | $medium: #aaaaaa; 5 | $mediumlight: #e5e5e5; 6 | $light: #f7f7f7; 7 | $white: #ffffff; 8 | $yellow: #f9f3b3; 9 | $yellowlight: #fbf7cb; 10 | 11 | $rainbow : ( 12 | 0: #9E23A5, 13 | 1: #AF2F5B, 14 | 2: #C23F23, 15 | 3: #D65F27, 16 | 4: #EE8A32, 17 | 5: #E4B83E, 18 | 6: #B7B83A, 19 | 7: #A0B438, 20 | 8: #6FAC33, 21 | 9: #4DA698, 22 | 10: #3E87AD, 23 | 11: #265ACC, 24 | 12: #413ACC 25 | ); 26 | 27 | $color__background-body: $light; 28 | $color__background-alt: $white; 29 | $color__background-translucent: rgba($color__background-body, 0.8); 30 | $color__background-screen: $mediumlight; 31 | $color__background-hr: mix($medium, $mediumlight); 32 | $color__background-button: $light; 33 | $color__background-button-fill: $dark; 34 | $color__background-pre: $mediumlight; 35 | $color__background-ins: $light; 36 | 37 | $color__button: $dark; 38 | $color__button-fill: $white; 39 | $color__nav-link: $mediumdark; 40 | $color__nav-link-hover: $dark; 41 | $color__breadcrumb-link: lighten($mediumdark, 10); 42 | $color__breadcrumb-hover: $dark; 43 | $color__text-main: $dark; 44 | $color__text-meta: $mediumdark; 45 | 46 | $color__text-screen: #21759b; 47 | $color__text-button: $dark; 48 | $color__text-input: #666; 49 | $color__text-input-focus: #111; 50 | $color__link: $dark; 51 | $color__link-hover: $dark; 52 | $color__link-visited: $mediumdark; 53 | $color__border-link: $mediumlight; 54 | $color__border-link-hover: $dark; 55 | 56 | $color__border-button: $mediumlight; 57 | $color__border-button-hover: transparent; 58 | $color__border-input: $mediumlight; 59 | $color__border-abbr: #666; 60 | 61 | // map css variables to each of our sass color variables 62 | :root { 63 | --color__background-body: #{$color__background-body}; 64 | --color__background-alt: #{$color__background-alt}; 65 | --color__background-translucent: #{$color__background-translucent}; 66 | --color__background-screen: #{$color__background-screen}; 67 | --color__background-hr: #{$color__background-hr}; 68 | --color__background-button: #{$color__background-button}; 69 | --color__background-button-fill: #{$color__background-button-fill}; 70 | --color__background-pre: #{$color__background-pre}; 71 | --color__background-ins: #{$color__background-ins}; 72 | 73 | --color__button: #{ $color__button }; 74 | --color__button-fill: #{ $color__button-fill }; 75 | --color__nav-link: #{ $color__nav-link }; 76 | --color__nav-link-hover: #{ $color__nav-link-hover }; 77 | --color__breadcrumb-link: #{ $color__breadcrumb-link }; 78 | --color__breadcrumb-hover: #{ $color__breadcrumb-hover }; 79 | --color__text-main: #{ $color__text-main }; 80 | --color__text-meta: #{ $color__text-meta }; 81 | 82 | --color__text-screen: #{ $color__text-screen }; 83 | --color__text-input: #{ $color__text-input }; 84 | --color__text-input-focus: #{ $color__text-input-focus }; 85 | --color__link: #{ $color__link }; 86 | --color__link-hover: #{ $color__link-hover }; 87 | --color__link-visited: #{ $color__link-visited }; 88 | --color__border-link: #{ $color__border-link }; 89 | --color__border-link-hover: #{ $color__border-link-hover }; 90 | 91 | --color__border-button: #{ $color__border-button }; 92 | --color__border-button-hover: #{ $color__border-button-hover }; 93 | --color__border-input: #{ $color__border-input }; 94 | --color__border-abbr: #{ $color__border-abbr }; 95 | } -------------------------------------------------------------------------------- /template-parts/content.php: -------------------------------------------------------------------------------- 1 | 11 | 12 |
> 13 | 14 |
15 | ', '' ); 20 | else : 21 | the_title( '

', '

' ); 22 | endif; 23 | 24 | if ( ( 'post' === get_post_type() ) || ( 'life_bookmark' === get_post_type() ) ) : 25 | ?> 26 |
27 | 30 |
31 | 32 |
33 | 34 |
35 | ' . $note_sticky . '
'; 42 | endif; 43 | } 44 | 45 | the_content( 46 | sprintf( 47 | wp_kses( 48 | /* translators: %s: Name of current post. Only visible to screen readers */ 49 | __( 'Continue reading "%s"', 'life' ), 50 | array( 51 | 'span' => array( 52 | 'class' => array(), 53 | ), 54 | ) 55 | ), 56 | wp_kses_post( get_the_title() ) 57 | ) 58 | ); 59 | 60 | if ( 'life_bookmark' === get_post_type() ) { 61 | 62 | $url = get_post_meta( get_the_ID(), 'life_url', true ); 63 | echo '

' . esc_html__( 'External Link', 'life' ) . '

'; 64 | echo '' . $url . ''; 65 | 66 | } 67 | 68 | wp_link_pages( 69 | array( 70 | 'before' => '', 72 | ) 73 | ); 74 | ?> 75 |
76 | 77 | 133 | 134 | -------------------------------------------------------------------------------- /library/sass/components/navigation/_misc.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | .comment-navigation, 4 | .post-navigation { 5 | margin: 0 0 1.5em; 6 | } 7 | 8 | .nav-links { 9 | align-items: center; 10 | display: flex; 11 | justify-content: space-between; 12 | 13 | > * { 14 | flex: 1; 15 | } 16 | 17 | .single & { 18 | flex-direction: row-reverse; 19 | } 20 | } 21 | 22 | .pagination { 23 | margin: 0 0 1.5em; 24 | 25 | &-numbers { 26 | display: none; 27 | 28 | @media screen and ($medium-up) { 29 | display: flex; 30 | justify-content: center; 31 | } 32 | } 33 | } 34 | 35 | .page-numbers { 36 | @include button('tag'); 37 | margin-bottom: 0; 38 | margin-right: 0.125rem; 39 | margin-left: 0.125rem; 40 | 41 | &.current { 42 | background: var(--color__background-alt); 43 | border-color: transparent; 44 | } 45 | } 46 | 47 | 48 | /*-------------------------------------------------------------- 49 | ## Prev/Next & Return Links 50 | --------------------------------------------------------------*/ 51 | 52 | .nav-title { 53 | font-weight: bold; 54 | } 55 | 56 | .nav-label { 57 | font-family: var(--font__alt); 58 | font-size: $typesize__small; 59 | letter-spacing: $font__letter-spacing; 60 | padding-top: 0.25em; 61 | text-transform: uppercase; 62 | transition: all 0.125s; 63 | 64 | @media screen and ($small-down) { 65 | font-size: $typesize__tiny; 66 | } 67 | } 68 | 69 | .nav-previous a, 70 | .nav-next a, 71 | .return-link a { 72 | display: inline-flex; 73 | text-decoration: none; 74 | } 75 | 76 | .nav-previous, 77 | .nav-next, 78 | .return-link { 79 | padding-top: 2rem; 80 | padding-bottom: 2rem; 81 | 82 | .icon-arrow { 83 | font-size: 1.25rem; 84 | } 85 | } 86 | 87 | .post-navigation + .return-link { 88 | border-top: 1px solid var(--color__background-hr); 89 | } 90 | 91 | 92 | /*-------------------------------------------------------------- 93 | ## Prev/Next 94 | --------------------------------------------------------------*/ 95 | 96 | .nav-previous, 97 | .nav-next { 98 | align-content: center; 99 | display: flex; 100 | } 101 | 102 | .nav-previous a, 103 | .nav-next a { 104 | flex-direction: column; 105 | position: relative; 106 | 107 | &::before { 108 | @include icon-style; 109 | font-size: 1.25rem; 110 | position: absolute; 111 | top: 0; 112 | transition: all 0.125s; 113 | transform: translateX(0); 114 | 115 | @media screen and ($medium-up) { 116 | top: 0.125em; 117 | } 118 | } 119 | } 120 | 121 | .nav-next a { 122 | align-items: flex-start; 123 | padding-left: 1.75rem; // make space for icon 124 | 125 | &::before { 126 | content: $icon-arrow-left; 127 | left: 0; 128 | padding-right: 0.5em; 129 | } 130 | 131 | &:hover::before, 132 | &:focus::before { 133 | transform: translateX(-0.25rem); 134 | } 135 | } 136 | 137 | .nav-previous { 138 | justify-content: end; 139 | 140 | a { 141 | margin-left: auto; // safari 142 | padding-right: 1.75rem; // make space for icon 143 | text-align: right; 144 | 145 | &::before { 146 | content: $icon-arrow-right; 147 | padding-left: 0.5em; 148 | right: 0; 149 | } 150 | 151 | &:hover::before, 152 | &:focus::before { 153 | transform: translateX(0.25rem); 154 | } 155 | } 156 | } 157 | 158 | 159 | /*-------------------------------------------------------------- 160 | ## Return Links 161 | --------------------------------------------------------------*/ 162 | 163 | .return-link { 164 | 165 | a { 166 | align-items: center; 167 | } 168 | 169 | .nav-label { 170 | margin: 0 0.5rem; 171 | } 172 | } 173 | 174 | 175 | /*-------------------------------------------------------------- 176 | ## Taxonomy Term Links 177 | --------------------------------------------------------------*/ 178 | 179 | .tags-links a { 180 | @include button('tag'); 181 | } 182 | -------------------------------------------------------------------------------- /library/sass/components/content/_posts-and-pages.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | /*-------------------------------------------------------------- 4 | ## Entry Header 5 | --------------------------------------------------------------*/ 6 | 7 | .featured-image { 8 | @include full-width; 9 | @extend %square-ish; 10 | display: block; // for ones that are 11 | 12 | @media screen and ($xlarge-up) { 13 | text-align: center; 14 | } 15 | } 16 | 17 | .entry-header { 18 | margin-bottom: 2rem; 19 | 20 | @media screen and ($large-up) { 21 | margin-bottom: 3rem; 22 | } 23 | 24 | @media screen and ($xlarge-up) { 25 | padding-top: 1rem; 26 | margin-bottom: 3rem; 27 | } 28 | } 29 | 30 | 31 | /*-------------------------------------------------------------- 32 | ## Entry Content 33 | --------------------------------------------------------------*/ 34 | 35 | .entry-content { 36 | display: flex; 37 | flex-direction: column; 38 | 39 | @media screen and ($large-up) { 40 | display: block; 41 | } 42 | } 43 | 44 | .note-sticky { 45 | background: $yellowlight; 46 | box-shadow: 0 0.25rem 1rem rgba($black, 0.08); 47 | color: $dark; 48 | font-family: var(--font__alt); 49 | margin-left: auto; 50 | margin-right: auto; 51 | order: 1; 52 | padding: 1rem 1.5rem; 53 | text-align: left; 54 | width: 14rem; 55 | 56 | p { 57 | font-size: $typesize__base; // reset 58 | } 59 | 60 | @media screen and ($large-up) { 61 | float: right; 62 | order: 0; 63 | margin-left: 2rem; 64 | margin-bottom: 2rem; 65 | } 66 | } 67 | 68 | 69 | /*-------------------------------------------------------------- 70 | ## Entry Footer 71 | --------------------------------------------------------------*/ 72 | 73 | .entry-footer { 74 | margin-top: 2rem; 75 | margin-bottom: 3rem; 76 | text-align: center; 77 | 78 | .tags-links { 79 | margin-bottom: 2rem; 80 | } 81 | 82 | @media screen and ($medium-up) { 83 | margin-top: 2rem; 84 | margin-bottom: 2rem; 85 | } 86 | 87 | @media screen and ($large-up) { 88 | margin-top: 4rem; 89 | margin-bottom: 4rem; 90 | } 91 | } 92 | 93 | .song-link { 94 | font-family: var(--font__alt); 95 | display: flex; 96 | flex-direction: column; 97 | margin-top: 1rem; 98 | margin-bottom: 2rem; 99 | 100 | .icon-music { 101 | margin-left: 0.25em; 102 | margin-right: 0.5em; 103 | vertical-align: middle; 104 | } 105 | 106 | .label { 107 | font-size: $typesize__tiny; 108 | letter-spacing: $font__letter-spacing; 109 | margin-top: 1em; 110 | margin-bottom: 0.5em; 111 | text-transform: uppercase; 112 | } 113 | 114 | .content { 115 | font-size: $typesize__small; 116 | } 117 | } 118 | 119 | .related-posts { 120 | margin-top: 3rem; 121 | 122 | .heading-alt { 123 | text-align: center; 124 | } 125 | 126 | .thumbnail { 127 | border-radius: 50%; 128 | height: 3rem; 129 | margin: 0.5rem; 130 | overflow: hidden; 131 | width: 3rem; 132 | } 133 | 134 | .grid-container { 135 | margin-top: 2rem; 136 | } 137 | } 138 | 139 | 140 | /*-------------------------------------------------------------- 141 | ## Archive Pages 142 | --------------------------------------------------------------*/ 143 | 144 | .blog { 145 | 146 | .post { 147 | border-bottom: 1px solid var(--color__background-hr); 148 | margin-bottom: 3rem; 149 | } 150 | 151 | .entry-title a { 152 | text-decoration: none; 153 | } 154 | } 155 | 156 | .post-type-archive-life_bookmark .narrow-container .heading-alt { 157 | color: var(--color__text-meta); 158 | margin-top: 2rem; 159 | } 160 | 161 | 162 | /*-------------------------------------------------------------- 163 | ## Miscellaneous 164 | --------------------------------------------------------------*/ 165 | 166 | .error-404 { 167 | @include wrap; 168 | 169 | } 170 | 171 | .updated:not(.published) { 172 | display: none; 173 | } -------------------------------------------------------------------------------- /inc/customizer.php: -------------------------------------------------------------------------------- 1 | get_setting( 'blogname' )->transport = 'postMessage'; 15 | $wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage'; 16 | 17 | if ( isset( $wp_customize->selective_refresh ) ) { 18 | $wp_customize->selective_refresh->add_partial( 19 | 'blogname', 20 | array( 21 | 'selector' => '.site-title a', 22 | 'render_callback' => 'life_customize_partial_blogname', 23 | ) 24 | ); 25 | $wp_customize->selective_refresh->add_partial( 26 | 'blogdescription', 27 | array( 28 | 'selector' => '.site-description', 29 | 'render_callback' => 'life_customize_partial_blogdescription', 30 | ) 31 | ); 32 | } 33 | 34 | // add subfooter section 35 | $wp_customize->add_setting( 36 | 'life_subfooter', 37 | array( 38 | 'default' => 'Copyright 2022', 39 | 'type' => 'theme_mod', 40 | 'sanitize_callback' => 'wp_kses_post' 41 | ) 42 | ); 43 | $wp_customize->add_control( new WP_Customize_Control( 44 | $wp_customize, 45 | 'life_subfooter', 46 | array( 47 | 'label' => __( 'Subfooter', 'life' ), 48 | 'settings' => 'life_subfooter', 49 | 'priority' => 10, 50 | 'section' => 'title_tagline', 51 | 'type' => 'text', 52 | ) 53 | ) ); 54 | 55 | // add rss email reply-to field 56 | $wp_customize->add_setting( 57 | 'life_rss_email', 58 | array( 59 | 'type' => 'theme_mod', 60 | 'sanitize_callback' => 'wp_kses_post' 61 | ) 62 | ); 63 | $wp_customize->add_control( new WP_Customize_Control( 64 | $wp_customize, 65 | 'life_rss_email', 66 | array( 67 | 'label' => __( 'Reply Email', 'life' ), 68 | 'description' => __( 'Specify an email address to be added to RSS feed reply-to links. Leave blank to exclude this link.', 'life' ), 69 | 'settings' => 'life_rss_email', 70 | 'priority' => 11, 71 | 'section' => 'title_tagline', 72 | 'type' => 'email', 73 | ) 74 | ) ); 75 | 76 | // add custom link color options 77 | $wp_customize->add_setting( 'link_color', array( 78 | 'default' => '#191919', 79 | 'type' => 'option', 80 | 'capability' => 'edit_theme_options', 81 | 'sanitize_callback' => 'sanitize_hex_color' 82 | )); 83 | $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'link_color', array( 84 | 'label' => __( 'Default Link Color', 'life' ), 85 | 'section' => 'colors', 86 | 'settings' => 'link_color' 87 | ))); 88 | $wp_customize->add_setting( 'link_color_dark', array( 89 | 'default' => '#e6e6e6', 90 | 'type' => 'option', 91 | 'capability' => 'edit_theme_options', 92 | 'sanitize_callback' => 'sanitize_hex_color' 93 | )); 94 | $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'link_color_dark', array( 95 | 'label' => __( 'Dark Mode Link Color', 'life' ), 96 | 'section' => 'colors', 97 | 'settings' => 'link_color_dark' 98 | ))); 99 | } 100 | add_action( 'customize_register', 'life_customize_register' ); 101 | 102 | /** 103 | * Render the site title for the selective refresh partial. 104 | * 105 | * @return void 106 | */ 107 | function life_customize_partial_blogname() { 108 | bloginfo( 'name' ); 109 | } 110 | 111 | /** 112 | * Render the site tagline for the selective refresh partial. 113 | * 114 | * @return void 115 | */ 116 | function life_customize_partial_blogdescription() { 117 | bloginfo( 'description' ); 118 | } 119 | 120 | /** 121 | * Binds JS handlers to make Theme Customizer preview reload changes asynchronously. 122 | */ 123 | function life_customize_preview_js() { 124 | wp_enqueue_script( 'life-customizer', get_template_directory_uri() . '/js/customizer.js', array( 'customize-preview' ), LIFE_VERSION, true ); 125 | } 126 | add_action( 'customize_preview_init', 'life_customize_preview_js' ); -------------------------------------------------------------------------------- /inc/bookmarks-meta.php: -------------------------------------------------------------------------------- 1 | config = json_decode( $this->config, true ); 15 | $this->process_cpts(); 16 | add_action( 'add_meta_boxes', [ $this, 'add_meta_boxes' ] ); 17 | add_action( 'admin_head', [ $this, 'admin_head' ] ); 18 | add_action( 'save_post', [ $this, 'save_post' ] ); 19 | } 20 | 21 | public function process_cpts() { 22 | if ( !empty( $this->config['cpt'] ) ) { 23 | if ( empty( $this->config['post-type'] ) ) { 24 | $this->config['post-type'] = []; 25 | } 26 | $parts = explode( ',', $this->config['cpt'] ); 27 | $parts = array_map( 'trim', $parts ); 28 | $this->config['post-type'] = array_merge( $this->config['post-type'], $parts ); 29 | } 30 | } 31 | 32 | public function add_meta_boxes() { 33 | foreach ( $this->config['post-type'] as $screen ) { 34 | add_meta_box( 35 | sanitize_title( $this->config['title'] ), 36 | $this->config['title'], 37 | [ $this, 'add_meta_box_callback' ], 38 | $screen, 39 | $this->config['context'], 40 | $this->config['priority'] 41 | ); 42 | } 43 | } 44 | 45 | public function admin_head() { 46 | global $typenow; 47 | if ( in_array( $typenow, $this->config['post-type'] ) ) { 48 | ?>config['fields'] as $field ) { 54 | switch ( $field['type'] ) { 55 | case 'url': 56 | if ( isset( $_POST[ $field['id'] ] ) ) { 57 | $sanitized = esc_url_raw( $_POST[ $field['id'] ] ); 58 | update_post_meta( $post_id, $field['id'], $sanitized ); 59 | } 60 | break; 61 | default: 62 | if ( isset( $_POST[ $field['id'] ] ) ) { 63 | $sanitized = sanitize_text_field( $_POST[ $field['id'] ] ); 64 | update_post_meta( $post_id, $field['id'], $sanitized ); 65 | } 66 | } 67 | } 68 | } 69 | 70 | public function add_meta_box_callback() { 71 | echo '
' . $this->config['description'] . '
'; 72 | $this->fields_table(); 73 | } 74 | 75 | private function fields_table() { 76 | ?> 77 | config['fields'] as $field ) { 79 | ?> 80 | 81 | 82 | 85 | %s', 93 | $field['id'], $field['label'] 94 | ); 95 | } 96 | } 97 | 98 | private function field( $field ) { 99 | switch ( $field['type'] ) { 100 | default: 101 | $this->input( $field ); 102 | } 103 | } 104 | 105 | private function input( $field ) { 106 | printf( 107 | '', 108 | isset( $field['class'] ) ? $field['class'] : '', 109 | $field['id'], $field['id'], 110 | isset( $field['pattern'] ) ? "pattern='{$field['pattern']}'" : '', 111 | $field['type'], 112 | $this->value( $field ) 113 | ); 114 | } 115 | 116 | private function value( $field ) { 117 | global $post; 118 | if ( metadata_exists( 'post', $post->ID, $field['id'] ) ) { 119 | $value = get_post_meta( $post->ID, $field['id'], true ); 120 | } else if ( isset( $field['default'] ) ) { 121 | $value = $field['default']; 122 | } else { 123 | return ''; 124 | } 125 | return str_replace( '\u0027', "'", $value ); 126 | } 127 | 128 | } 129 | 130 | new Life_Bookmark_Meta_Boxes; -------------------------------------------------------------------------------- /phpcs.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A custom set of code standard rules to check for WordPress themes. 10 | 11 | 12 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | . 36 | 37 | 38 | /vendor/* 39 | /node_modules/* 40 | 41 | 42 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 59 | 60 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /inc/template-functions.php: -------------------------------------------------------------------------------- 1 | >" to "...". 41 | */ 42 | function life_excerpt_more($more) { 43 | global $post; 44 | return '...'; 45 | } 46 | add_filter('excerpt_more', 'life_excerpt_more'); 47 | 48 | /** 49 | * Add a pingback url auto-discovery header for single posts, pages, or attachments. 50 | */ 51 | function life_pingback_header() { 52 | if ( is_singular() && pings_open() ) { 53 | printf( '', esc_url( get_bloginfo( 'pingback_url' ) ) ); 54 | } 55 | } 56 | add_action( 'wp_head', 'life_pingback_header' ); 57 | 58 | /** 59 | * Add featured image and "currently listening" to RSS feed content or excerpt 60 | */ 61 | function life_rss_feed_excerpt( $content ) { 62 | 63 | global $post, $wp_query; 64 | 65 | $prepend = null; 66 | $append = null; 67 | 68 | $email = wp_kses_post( get_theme_mod('life_rss_email') ); 69 | 70 | if ( $email ) { 71 | $append = '

' . esc_html__( 'Reply via email ', 'life' ) . '

'; 72 | } 73 | 74 | if ( ! $wp_query->is_comment_feed() ) { 75 | 76 | if ( has_post_thumbnail( $post->ID ) ) { 77 | 78 | $prepend = '
' . get_the_post_thumbnail( $post->ID, 'medium', array( 'style' => 'margin-bottom: 16px;' ) ) . '
'; 79 | } 80 | 81 | if ( function_exists( 'get_field' ) ) { 82 | $song = get_field('song_link'); 83 | 84 | if ( $song ): 85 | $artist = get_field('song_artist'); 86 | $song_url = $song['url']; 87 | $song_title = $song['title']; 88 | $song_target = $song['target'] ? $song['target'] : '_self'; 89 | $content .= ''; 90 | endif; 91 | } 92 | 93 | $content = $prepend . $content . $append; 94 | 95 | } 96 | 97 | return $content; 98 | 99 | } 100 | add_filter('the_content_feed', 'life_rss_feed_excerpt'); 101 | add_filter('the_excerpt_rss', 'life_rss_feed_excerpt'); 102 | 103 | 104 | /** 105 | * Bookmarks/Links in RSS feed link directly to the referenced URL 106 | */ 107 | function life_rss_bookmark_url($post_permalink) { 108 | if ( 'life_bookmark' === get_post_type() ) { 109 | return get_post_meta( get_the_ID(), 'life_url', true ); 110 | } else { 111 | return $post_permalink; 112 | } 113 | }; 114 | add_filter('the_permalink_rss', 'life_rss_bookmark_url'); 115 | 116 | 117 | /** 118 | * Display featured image in admin columns 119 | * src: https://wordpress.stackexchange.com/a/114651 120 | */ 121 | function life_add_img_column( $columns ) { 122 | 123 | $columns['img'] = 'Image'; 124 | $array = array(); 125 | $img = $columns['img']; // save the img column 126 | unset($columns['img']); // remove it from the columns list 127 | 128 | foreach( $columns as $key=>$value ) { 129 | if ( $key=='title' ) { // when we find the title column 130 | $array['img'] = $img; // put the img column before it 131 | } 132 | $array[$key] = $value; 133 | } 134 | 135 | return $array; 136 | 137 | } 138 | add_filter('manage_posts_columns', 'life_add_img_column'); 139 | 140 | function life_manage_img_column( $column_name, $post_id ) { 141 | 142 | if ( $column_name == 'img' ) { 143 | echo get_the_post_thumbnail($post_id, 'small_square'); 144 | } 145 | 146 | return $column_name; 147 | 148 | } 149 | add_filter('manage_posts_custom_column', 'life_manage_img_column', 10, 2); -------------------------------------------------------------------------------- /library/sass/base/elements/_darkmode.scss: -------------------------------------------------------------------------------- 1 | @mixin darkMode() { 2 | 3 | // invert each sass color variable 4 | $color__background-body: invert( $color__background-body ); 5 | $color__background-alt: lighten( $color__background-body, 8 ); 6 | $color__background-translucent: rgba($color__background-body, 0.6); 7 | $color__background-screen: invert( $color__background-screen ); 8 | $color__background-hr: invert( $color__background-hr ); 9 | $color__background-button: invert( $color__background-button ); 10 | $color__background-button-fill: $color__background-button-fill; // don't change 11 | $color__background-pre: invert( $color__background-pre ); 12 | $color__background-ins: invert( $color__background-ins ); 13 | 14 | $color__button: invert( $color__button ); 15 | $color__button-fill: $color__button-fill; // don't change 16 | $color__nav-link: invert( $color__nav-link ); 17 | $color__nav-link-hover: invert( $color__nav-link-hover ); 18 | $color__breadcrumb-link: invert( $color__breadcrumb-link ); 19 | $color__breadcrumb-hover: invert( $color__breadcrumb-hover ); 20 | $color__text-main: invert( $color__text-main ); 21 | $color__text-meta: invert( $color__text-meta ); 22 | 23 | $color__text-screen: invert( $color__text-screen ); 24 | $color__text-input: $color__text-input; 25 | $color__text-input-focus: $color__text-input-focus; 26 | $color__link: invert( $color__link ); 27 | $color__link-hover: invert( $color__link-hover ); 28 | $color__link-visited: invert( $color__link-visited ); 29 | $color__border-link: lighten( invert( $color__border-link ), 12); 30 | $color__border-link-hover: invert( $color__border-link-hover ); 31 | 32 | $color__border-button: invert( $color__border-button ); 33 | $color__border-button-hover: lighten( $color__border-button, 5 ); 34 | $color__border-input: invert( $color__border-input ); 35 | $color__border-abbr: invert( $color__border-abbr ); 36 | 37 | // reassign sass color variables to css variables 38 | --color__background-body: #{$color__background-body}; 39 | --color__background-alt: #{$color__background-alt}; 40 | --color__background-translucent: #{$color__background-translucent}; 41 | --color__background-screen: #{$color__background-screen}; 42 | --color__background-hr: #{$color__background-hr}; 43 | --color__background-button: #{$color__background-button}; 44 | --color__background-button-fill: #{$color__background-button-fill}; 45 | --color__background-pre: #{$color__background-pre}; 46 | --color__background-ins: #{$color__background-ins}; 47 | 48 | --color__button: #{ $color__button }; 49 | --color__button-fill: #{ $color__button-fill }; 50 | --color__nav-link: #{ $color__nav-link }; 51 | --color__nav-link-hover: #{ $color__nav-link-hover }; 52 | --color__breadcrumb-link: #{ $color__breadcrumb-link }; 53 | --color__breadcrumb-hover: #{ $color__breadcrumb-hover }; 54 | --color__text-main: #{ $color__text-main }; 55 | --color__text-meta: #{ $color__text-meta }; 56 | 57 | --color__text-screen: #{ $color__text-screen }; 58 | --color__text-input: #{ $color__text-input }; 59 | --color__text-input-focus: #{ $color__text-input-focus }; 60 | --color__link: #{ $color__link }; 61 | --color__link-hover: #{ $color__link-hover }; 62 | --color__link-visited: #{ $color__link-visited }; 63 | --color__border-link: #{ $color__border-link }; 64 | --color__border-link-hover: #{ $color__border-link-hover }; 65 | 66 | --color__border-button: #{ $color__border-button }; 67 | --color__border-button-hover: #{ $color__border-button-hover }; 68 | --color__border-input: #{ $color__border-input }; 69 | --color__border-abbr: #{ $color__border-abbr }; 70 | 71 | // // tweak color on some elements 72 | .site-header .search-field { 73 | background-color: $black; 74 | border-color: $black; 75 | 76 | &:focus-visible { 77 | border-color: $medium; 78 | } 79 | } 80 | 81 | .wp-block-table.is-style-stripes tbody tr:nth-child(2n+1) { 82 | background-color: var(--color__background-alt); 83 | } 84 | 85 | ::selection { 86 | background-color: $mediumdark; 87 | } 88 | 89 | .toggle-mode .icon-sun { 90 | background: transparent; 91 | color: $black; 92 | } 93 | 94 | .toggle-mode .icon-moon { 95 | background: $dark; 96 | color: $white; 97 | } 98 | 99 | select { 100 | color: $black; 101 | } 102 | } 103 | 104 | // if switcher has added .dark, do Dark Mode 105 | .dark { 106 | @include darkMode; 107 | } 108 | 109 | // if system preference is dark, and switcher hasn't specified .light, do Dark Mode 110 | @media (prefers-color-scheme: dark) { 111 | 112 | html:not(.light) { 113 | @include darkMode; 114 | } 115 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Life Theme 2 | === 3 | 4 | Minimalist WordPress theme designed by Chris Glass and built by Kay Belardinelli. 5 | 6 | ![Website Branding](screenshot.png) 7 | 8 | Theme Installation 9 | ------------ 10 | 11 | * download the [zip file here](https://chrisglass.com/wp-content/uploads/2023/12/lifetheme-1.8.3.zip) 12 | * in the WP admin, go to Appearance > Themes > Add New, then click “Upload Theme”; upload the zip file 13 | * click “activate” 14 | 15 | Recommended Setup 16 | -------------------------------- 17 | 18 | * create a page for homepage, put whatever you want in it 19 | * create a page for posts/blog, put nothing in it 20 | * Settings > Reading, under “Your homepage displays” select “A static page”, then set “Homepage” and “Posts page” to the corresponding pages you just made. 21 | * Settings > Reading, under “Blog pages show at most”, choose a number divisible by 15 (e.g. 15, 30, 60). This will create the optimal grid layout for Favorites and Characters archive pages. Note this settings does not apply to the Posts page, which is set by the theme to 12. 22 | 23 | Widget Areas 24 | ------------ 25 | 26 | ### Headers (Blog, Projects, Characters, Links, Favorites) 27 | 28 | These allow you to customize what appears in the header of the different sections of the website. Add a “Text” widget, and the title will appear as the page heading, along with a paragraph of text in the content of the widget (optional). 29 | 30 | ### Secondary Content Areas (Homepage, Posts, Links Archives) 31 | 32 | Add any content here that you wish, and it will appear below the main content. 33 | 34 | Theme Options 35 | ------------- 36 | 37 | Appearance > Customize 38 | 39 | ### Site Identity 40 | 41 | * Site Title: appears in the site header, and browser tab/bookmark 42 | * Tagline: appears in the browser tab/bookmark of homepage, and (optional) in the site header 43 | * Subfooter: add copyright, privacy, and other info here 44 | * Display Site Title and Tagline: this toggles the Tagline in the site header 45 | * Site Icon: add a custom icon to appear in your browser tab/bookmarks 46 | * Reply Email: add a contact email to display a reply link in RSS feeds 47 | 48 | ### Colors 49 | 50 | * Link Color: Select any color for text links throughout the site. 51 | * Dark Mode Link Color: Same as above, but for Dark Mode. 52 | 53 | Post Types 54 | ---------- 55 | 56 | * Posts: the default WordPress post type (generally used as a blog) 57 | * Projects: use this as a portfolio or to display your finished projects, etc. 58 | * Favorites: show off all your favorite things <3 59 | * Links: link to external websites to share with your readers 60 | 61 | Menus 62 | ----- 63 | 64 | ### Locations 65 | 66 | * Primary: Drawer/”Hamburger” navigation. Allows up to two levels of depth. 67 | * Secondary: Horizontal in site header, desktop only (optional) 68 | * Footer (optional) 69 | * Projects Submenu (optional): Add links to your Collections here. Can work as a filter for Collections. 70 | * Links Submenu (optional): Add links to your Link Types here. Can work as a filter for Link Types. 71 | * Favorites Submenu (optional): Add links to your Favorite Types here. Can work as a filter for Favorite Types. 72 | 73 | ### Adding Website Sections 74 | 75 | * Go to Appearance > Menus 76 | * In the “Screen Options” tab in the upper right of the page, make sure the following items are checked: Projects, Characters, Links, Pins, Favorites 77 | * Projects > View All, then select “All Projects” and add to the menu; Repeat for the remaining post types 78 | 79 | Custom Fields 80 | ------------- 81 | 82 | * “Currently Listening”: Link to an external song or album. 83 | * Related Characters / Related Posts: Allows you to link Characters to posts and vice versa. These automatically correlate with each other, creating a recipricol relationship. Note: the " 84 | ACF Post-2-Post" plugin may required for this feature to fully work (to be tested). 85 | * Sticky Note: Add a little sticky note to any post. 86 | 87 | ### Installation 88 | 89 | * Install Advanced Custom Fields plugin 90 | * Go to Custom Fields > Tools; import the json file included in the theme folder 91 | * If using the Related Characters / Related Posts feature, the add-on plugin "ACF Post-2-Post" is recommended. 92 | 93 | WooCommerce 94 | ----------- 95 | 96 | This theme offers basic support for WooCommerce. 97 | 98 | Development 99 | ----------- 100 | 101 | * Clone this git repository. 102 | * The repository does not track css, so the sass must be compiled to css for the theme to work. `cd library` and run `sass --watch sass:css` or something similar. -------------------------------------------------------------------------------- /library/js/navigation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * File navigation.js. 3 | */ 4 | 5 | /*-------------------------------------------------------------- 6 | ## Navigation Menu 7 | ** Handles toggling the navigation menu for small screens and enables TAB key 8 | ** navigation support for dropdown menus. 9 | --------------------------------------------------------------*/ 10 | 11 | ( function() { 12 | var html, container, button, menu, links, i, len; 13 | 14 | html = document.getElementsByTagName( 'html' )[0]; 15 | 16 | container = document.getElementById( 'site-navigation' ); 17 | if ( ! container ) { 18 | return; 19 | } 20 | 21 | button = container.getElementsByTagName( 'button' )[0]; 22 | if ( 'undefined' === typeof button ) { 23 | return; 24 | } 25 | 26 | menu = container.getElementsByTagName( 'ul' )[0]; 27 | 28 | // Hide menu toggle button if menu is empty and return early. 29 | if ( 'undefined' === typeof menu ) { 30 | button.style.display = 'none'; 31 | return; 32 | } 33 | 34 | menu.setAttribute( 'aria-expanded', 'false' ); 35 | if ( -1 === menu.className.indexOf( 'nav-menu' ) ) { 36 | menu.className += ' nav-menu'; 37 | } 38 | 39 | function closeMenu() { 40 | html.className = html.className.replace( ' menu-open', '' ); 41 | container.className = container.className.replace( ' toggled', '' ); 42 | button.setAttribute( 'aria-expanded', 'false' ); 43 | menu.setAttribute( 'aria-expanded', 'false' ); 44 | } 45 | 46 | function openMenu() { 47 | html.className += ' menu-open'; 48 | container.className += ' toggled'; 49 | button.setAttribute( 'aria-expanded', 'true' ); 50 | menu.setAttribute( 'aria-expanded', 'true' ); 51 | } 52 | 53 | // toggle menu open/close with button 54 | button.onclick = function() { 55 | if ( -1 !== container.className.indexOf( 'toggled' ) ) { 56 | closeMenu(); 57 | } else { 58 | openMenu(); 59 | } 60 | }; 61 | 62 | // close menu using ESC key 63 | document.onkeydown = function(evt) { 64 | evt = evt || window.event; 65 | var isEscape = false; 66 | if ("key" in evt) { 67 | isEscape = (evt.key === "Escape" || evt.key === "Esc"); 68 | } else { 69 | isEscape = (evt.keyCode === 27); 70 | } 71 | if (isEscape) { 72 | closeMenu(); 73 | } 74 | }; 75 | 76 | // close menu if you click outside it 77 | document.addEventListener("click", function(evt) { 78 | targetElement = evt.target; // clicked element 79 | 80 | do { 81 | if (targetElement == container) { 82 | return; 83 | } 84 | targetElement = targetElement.parentNode; 85 | } while (targetElement); 86 | 87 | closeMenu(); 88 | }); 89 | 90 | // Get all the link elements within the menu. 91 | links = menu.getElementsByTagName( 'a' ); 92 | 93 | // Each time a menu link is focused or blurred, toggle focus. 94 | for ( i = 0, len = links.length; i < len; i++ ) { 95 | links[i].addEventListener( 'focus', toggleFocus, true ); 96 | links[i].addEventListener( 'blur', toggleFocus, true ); 97 | } 98 | 99 | /** 100 | * Sets or removes .focus class on an element. 101 | */ 102 | function toggleFocus() { 103 | var self = this; 104 | 105 | // Move up through the ancestors of the current link until we hit .nav-menu. 106 | while ( -1 === self.className.indexOf( 'nav-menu' ) ) { 107 | 108 | // On li elements toggle the class .focus. 109 | if ( 'li' === self.tagName.toLowerCase() ) { 110 | if ( -1 !== self.className.indexOf( 'focus' ) ) { 111 | self.className = self.className.replace( ' focus', '' ); 112 | } else { 113 | self.className += ' focus'; 114 | } 115 | } 116 | 117 | self = self.parentElement; 118 | } 119 | } 120 | 121 | } )(); 122 | 123 | /*-------------------------------------------------------------- 124 | # Dark Mode detection & toggle 125 | --------------------------------------------------------------*/ 126 | 127 | jQuery(document).ready( function($) { 128 | 129 | $( 'html' ).toggleClass( localStorage.toggled ); 130 | 131 | const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)'); 132 | 133 | function darkMode() { 134 | $( 'html' ).toggleClass( 'dark', true ); 135 | $( 'html' ).toggleClass( 'light', false ); 136 | localStorage.toggled = 'dark'; 137 | $( '.toggle-mode' ).attr( 'aria-checked', true ); 138 | } 139 | 140 | function lightMode() { 141 | $( 'html' ).toggleClass( 'dark', false ); 142 | $( 'html' ).toggleClass( 'light', true ); 143 | localStorage.toggled = 'light'; 144 | $( '.toggle-mode' ).attr( 'aria-checked', false ); 145 | } 146 | 147 | // if dark mode system pref is detected, and localStorage preference isn't set to "light", 148 | // mark the toggle as checked on load 149 | if ( prefersDarkScheme.matches && localStorage.toggled != 'light' ) { 150 | $( '.toggle-mode' ).attr( 'aria-checked', true ); 151 | console.log("prefersDarkScheme.matches && localStorage.toggled != 'light'"); 152 | } 153 | 154 | // switch to the opposite mode with the toggle is clicked 155 | $( '.toggle-mode' ).click( function() { 156 | 157 | if ( !prefersDarkScheme.matches && localStorage.toggled != 'dark' ) { 158 | darkMode(); 159 | } 160 | else if ( prefersDarkScheme.matches && localStorage.toggled != 'light' ) { 161 | lightMode(); 162 | } else if ( !prefersDarkScheme.matches && localStorage.toggled == 'dark' ) { 163 | lightMode(); 164 | } else { 165 | darkMode(); 166 | } 167 | }); 168 | 169 | } ); 170 | -------------------------------------------------------------------------------- /inc/woocommerce.php: -------------------------------------------------------------------------------- 1 | 150, 24 | 'single_image_width' => 300, 25 | 'product_grid' => array( 26 | 'default_rows' => 3, 27 | 'min_rows' => 1, 28 | 'default_columns' => 4, 29 | 'min_columns' => 1, 30 | 'max_columns' => 6, 31 | ), 32 | ) 33 | ); 34 | add_theme_support( 'wc-product-gallery-zoom' ); 35 | add_theme_support( 'wc-product-gallery-lightbox' ); 36 | add_theme_support( 'wc-product-gallery-slider' ); 37 | } 38 | add_action( 'after_setup_theme', 'life_woocommerce_setup' ); 39 | 40 | /** 41 | * Add 'woocommerce-active' class to the body tag. 42 | * 43 | * @param array $classes CSS classes applied to the body tag. 44 | * @return array $classes modified to include 'woocommerce-active' class. 45 | */ 46 | function life_woocommerce_active_body_class( $classes ) { 47 | $classes[] = 'woocommerce-active'; 48 | 49 | return $classes; 50 | } 51 | add_filter( 'body_class', 'life_woocommerce_active_body_class' ); 52 | 53 | /** 54 | * Remove default WooCommerce wrapper. 55 | */ 56 | remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10 ); 57 | remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10 ); 58 | 59 | if ( ! function_exists( 'life_woocommerce_wrapper_before' ) ) { 60 | /** 61 | * Before Content. 62 | * 63 | * Wraps all WooCommerce content in wrappers which match the theme markup. 64 | * 65 | * @return void 66 | */ 67 | function life_woocommerce_wrapper_before() { 68 | ?> 69 |
70 | 85 |
86 | 101 | */ 102 | 103 | if ( ! function_exists( 'life_woocommerce_cart_link_fragment' ) ) { 104 | /** 105 | * Cart Fragments. 106 | * 107 | * Ensure cart contents update when products are added to the cart via AJAX. 108 | * 109 | * @param array $fragments Fragments to refresh via AJAX. 110 | * @return array Fragments to refresh via AJAX. 111 | */ 112 | function life_woocommerce_cart_link_fragment( $fragments ) { 113 | ob_start(); 114 | life_woocommerce_cart_link(); 115 | $fragments['a.cart-contents'] = ob_get_clean(); 116 | 117 | return $fragments; 118 | } 119 | } 120 | add_filter( 'woocommerce_add_to_cart_fragments', 'life_woocommerce_cart_link_fragment' ); 121 | 122 | if ( ! function_exists( 'life_woocommerce_cart_link' ) ) { 123 | /** 124 | * Cart Link. 125 | * 126 | * Displayed a link to the cart including the number of items present and the cart total. 127 | * 128 | * @return void 129 | */ 130 | function life_woocommerce_cart_link() { 131 | ?> 132 | 133 | cart->get_cart_contents_count(), '_s' ), 137 | WC()->cart->get_cart_contents_count() 138 | ); 139 | ?> 140 | cart->get_cart_subtotal() ); ?> 141 | 142 | 159 | 173 | a::before { 70 | @include icon-style; 71 | } 72 | 73 | .menu-icon > a:before { 74 | margin-right: 0.5em; 75 | vertical-align: -0.05em; 76 | } 77 | 78 | .icon-arrow-right, 79 | .menu-icon.arrow-right > a { 80 | display: inline-block; 81 | &:before { 82 | content: $icon-arrow-right; 83 | } 84 | } 85 | 86 | .icon-arrow-down, 87 | .menu-icon.arrow-down > a { 88 | &:before { 89 | content: $icon-arrow-down; 90 | } 91 | } 92 | 93 | .icon-arrow-left, 94 | .menu-icon.arrow-left > a { 95 | &:before { 96 | content: $icon-arrow-left; 97 | } 98 | } 99 | 100 | .icon-arrow-up, 101 | .menu-icon.arrow-up > a { 102 | &:before { 103 | content: $icon-arrow-up; 104 | } 105 | } 106 | 107 | .icon-arrow-down-double, 108 | .menu-icon.arrow-down-double > a { 109 | &:before { 110 | content: $icon-arrow-down-double; 111 | } 112 | } 113 | 114 | .icon-arrow-left-double, 115 | .menu-icon.arrow-left-double > a { 116 | &:before { 117 | content: $icon-arrow-left-double; 118 | } 119 | } 120 | 121 | .icon-arrow-right-double, 122 | .menu-icon.arrow-right-double > a { 123 | &:before { 124 | content: $icon-arrow-right-double; 125 | } 126 | } 127 | 128 | .icon-arrow-up-double, 129 | .menu-icon.arrow-up-double > a { 130 | &:before { 131 | content: $icon-arrow-up-double; 132 | } 133 | } 134 | 135 | .icon-bookmark, 136 | .menu-icon.bookmark > a { 137 | &:before { 138 | content: $icon-bookmark; 139 | } 140 | } 141 | 142 | .icon-camera, 143 | .menu-icon.camera > a { 144 | &:before { 145 | content: $icon-camera; 146 | } 147 | } 148 | 149 | .icon-clock, 150 | .menu-icon.clock > a { 151 | &:before { 152 | content: $icon-clock; 153 | } 154 | } 155 | 156 | .icon-heart, 157 | .menu-icon.heart > a { 158 | &:before { 159 | content: $icon-heart; 160 | } 161 | } 162 | 163 | .icon-home, 164 | .menu-icon.home > a { 165 | &:before { 166 | content: $icon-home; 167 | } 168 | } 169 | 170 | .icon-person, 171 | .menu-icon.person > a { 172 | &:before { 173 | content: $icon-person; 174 | } 175 | } 176 | 177 | .icon-project, 178 | .menu-icon.project > a { 179 | &:before { 180 | content: $icon-project; 181 | } 182 | } 183 | 184 | .icon-circle, 185 | .menu-icon.circle > a { 186 | &:before { 187 | content: $icon-circle; 188 | } 189 | } 190 | 191 | .icon-exit, 192 | .menu-icon.exit > a { 193 | &:before { 194 | content: $icon-exit; 195 | } 196 | } 197 | 198 | .icon-info, 199 | .menu-icon.info > a { 200 | &:before { 201 | content: $icon-info; 202 | } 203 | } 204 | 205 | .icon-moon, 206 | .menu-icon.moon > a { 207 | &:before { 208 | content: $icon-moon; 209 | } 210 | } 211 | 212 | .icon-music, 213 | .menu-icon.music > a { 214 | &:before { 215 | content: $icon-music; 216 | } 217 | } 218 | 219 | .icon-rss, 220 | .menu-icon.rss > a { 221 | &:before { 222 | content: $icon-rss; 223 | } 224 | } 225 | 226 | .icon-search, 227 | .menu-icon.search > a { 228 | &:before { 229 | content: $icon-search; 230 | } 231 | } 232 | 233 | .icon-star, 234 | .menu-icon.star > a { 235 | &:before { 236 | content: $icon-star; 237 | } 238 | } 239 | 240 | .icon-sun, 241 | .menu-icon.sun > a { 242 | &:before { 243 | content: $icon-sun; 244 | } 245 | } 246 | 247 | .icon-talk, 248 | .menu-icon.talk > a { 249 | &:before { 250 | content: $icon-talk; 251 | } 252 | } 253 | 254 | .icon-triangle, 255 | .menu-icon.triangle > a { 256 | &:before { 257 | content: $icon-triangle; 258 | } 259 | } 260 | 261 | .icon-globe, 262 | .menu-icon.globe > a { 263 | &:before { 264 | content: $icon-globe; 265 | } 266 | } 267 | 268 | .icon-new-window, 269 | .menu-icon.new-window > a { 270 | &:before { 271 | content: $icon-new-window; 272 | } 273 | } 274 | 275 | .icon-circle-arrow-up, 276 | .menu-icon.circle-arrow-up > a { 277 | &:before { 278 | content: $icon-circle-arrow-up; 279 | } 280 | } 281 | 282 | 283 | /*-------------------------------------------------------------- 284 | ## Arrow Hovers 285 | --------------------------------------------------------------*/ 286 | 287 | a .icon-arrow { 288 | display: inline-block; 289 | transition: all 0.125s; 290 | } 291 | 292 | a:hover .icon-arrow, 293 | a:focus .icon-arrow { 294 | 295 | &-up, 296 | &-up-double { 297 | transform: translateY(-0.25rem); 298 | } 299 | 300 | &-right, 301 | &-right-double { 302 | transform: translateX(0.25rem); 303 | } 304 | 305 | &-down, 306 | &-down-double { 307 | transform: translateY(0.25rem); 308 | } 309 | 310 | &-left, 311 | &-left-double { 312 | transform: translateX(-0.25rem); 313 | } 314 | } 315 | -------------------------------------------------------------------------------- /acf-export-2021-04-26.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "key": "group_601325bb18197", 4 | "title": "Currently Listening", 5 | "fields": [ 6 | { 7 | "key": "field_601325d2f458d", 8 | "label": "Artist Name", 9 | "name": "song_artist", 10 | "type": "text", 11 | "instructions": "", 12 | "required": 0, 13 | "conditional_logic": 0, 14 | "wrapper": { 15 | "width": "", 16 | "class": "", 17 | "id": "" 18 | }, 19 | "default_value": "", 20 | "placeholder": "", 21 | "prepend": "", 22 | "append": "", 23 | "maxlength": "" 24 | }, 25 | { 26 | "key": "field_60132777d12f7", 27 | "label": "Link", 28 | "name": "song_link", 29 | "type": "link", 30 | "instructions": "", 31 | "required": 0, 32 | "conditional_logic": 0, 33 | "wrapper": { 34 | "width": "", 35 | "class": "", 36 | "id": "" 37 | }, 38 | "return_format": "array" 39 | } 40 | ], 41 | "location": [ 42 | [ 43 | { 44 | "param": "post_type", 45 | "operator": "==", 46 | "value": "post" 47 | } 48 | ] 49 | ], 50 | "menu_order": 0, 51 | "position": "side", 52 | "style": "default", 53 | "label_placement": "top", 54 | "instruction_placement": "label", 55 | "hide_on_screen": "", 56 | "active": true, 57 | "description": "" 58 | }, 59 | { 60 | "key": "group_601330a987b1e", 61 | "title": "Related Characters", 62 | "fields": [ 63 | { 64 | "key": "field_601330b8c9ac5", 65 | "label": "Characters", 66 | "name": "characters_posts", 67 | "type": "relationship", 68 | "instructions": "", 69 | "required": 0, 70 | "conditional_logic": 0, 71 | "wrapper": { 72 | "width": "", 73 | "class": "", 74 | "id": "" 75 | }, 76 | "post_type": [ 77 | "life_character" 78 | ], 79 | "taxonomy": "", 80 | "filters": [ 81 | "search" 82 | ], 83 | "elements": [ 84 | "featured_image" 85 | ], 86 | "min": "", 87 | "max": "", 88 | "return_format": "object" 89 | } 90 | ], 91 | "location": [ 92 | [ 93 | { 94 | "param": "post_type", 95 | "operator": "==", 96 | "value": "post" 97 | } 98 | ], 99 | [ 100 | { 101 | "param": "post_type", 102 | "operator": "==", 103 | "value": "life_project" 104 | } 105 | ], 106 | [ 107 | { 108 | "param": "post_type", 109 | "operator": "==", 110 | "value": "life_favorite" 111 | } 112 | ] 113 | ], 114 | "menu_order": 0, 115 | "position": "normal", 116 | "style": "default", 117 | "label_placement": "top", 118 | "instruction_placement": "label", 119 | "hide_on_screen": "", 120 | "active": true, 121 | "description": "" 122 | }, 123 | { 124 | "key": "group_601453a512a8a", 125 | "title": "Related Posts", 126 | "fields": [ 127 | { 128 | "key": "field_601453a51989f", 129 | "label": "Posts", 130 | "name": "characters_posts", 131 | "type": "relationship", 132 | "instructions": "", 133 | "required": 0, 134 | "conditional_logic": 0, 135 | "wrapper": { 136 | "width": "", 137 | "class": "", 138 | "id": "" 139 | }, 140 | "post_type": [ 141 | "post", 142 | "life_project", 143 | "life_favorite" 144 | ], 145 | "taxonomy": "", 146 | "filters": [ 147 | "search" 148 | ], 149 | "elements": [ 150 | "featured_image" 151 | ], 152 | "min": "", 153 | "max": "", 154 | "return_format": "object" 155 | } 156 | ], 157 | "location": [ 158 | [ 159 | { 160 | "param": "post_type", 161 | "operator": "==", 162 | "value": "life_character" 163 | } 164 | ] 165 | ], 166 | "menu_order": 0, 167 | "position": "normal", 168 | "style": "default", 169 | "label_placement": "top", 170 | "instruction_placement": "label", 171 | "hide_on_screen": "", 172 | "active": true, 173 | "description": "" 174 | }, 175 | { 176 | "key": "group_605b8657516e3", 177 | "title": "Sticky Note", 178 | "fields": [ 179 | { 180 | "key": "field_605b8664f307f", 181 | "label": "Sticky Note", 182 | "name": "note_sticky", 183 | "type": "textarea", 184 | "instructions": "", 185 | "required": 0, 186 | "conditional_logic": 0, 187 | "wrapper": { 188 | "width": "", 189 | "class": "", 190 | "id": "" 191 | }, 192 | "default_value": "", 193 | "placeholder": "", 194 | "maxlength": 300, 195 | "rows": "", 196 | "new_lines": "br" 197 | } 198 | ], 199 | "location": [ 200 | [ 201 | { 202 | "param": "post_type", 203 | "operator": "!=", 204 | "value": "page" 205 | }, 206 | { 207 | "param": "post_type", 208 | "operator": "!=", 209 | "value": "life_bookmark" 210 | } 211 | ] 212 | ], 213 | "menu_order": 0, 214 | "position": "side", 215 | "style": "default", 216 | "label_placement": "top", 217 | "instruction_placement": "label", 218 | "hide_on_screen": "", 219 | "active": true, 220 | "description": "" 221 | } 222 | ] -------------------------------------------------------------------------------- /inc/template-tags.php: -------------------------------------------------------------------------------- 1 | %2$s'; 16 | if ( get_the_time( 'U' ) !== get_the_modified_time( 'U' ) ) { 17 | $time_string = ''; 18 | } 19 | 20 | $time_string = sprintf( 21 | $time_string, 22 | esc_attr( get_the_date( DATE_W3C ) ), 23 | esc_html( get_the_date() ), 24 | esc_attr( get_the_modified_date( DATE_W3C ) ), 25 | esc_html( get_the_modified_date() ) 26 | ); 27 | 28 | echo $time_string; 29 | 30 | } 31 | endif; 32 | 33 | if ( ! function_exists( 'life_listening' ) ) : 34 | /** 35 | * Returns "Currently Listening" info, if it exists. For use in life_entry_footer() 36 | */ 37 | function life_listening() { 38 | 39 | if ( function_exists( 'get_field' ) ) { 40 | $artist = get_field('song_artist'); 41 | $song = get_field('song_link'); 42 | 43 | if ( $song ): 44 | 45 | $song_url = $song['url']; 46 | $song_title = $song['title']; 47 | $song_target = $song['target'] ? $song['target'] : '_self'; 48 | $icon = ''; 49 | $label = '' . esc_html__( 'Currently Listening', 'life' ) . ' '; 50 | $content = '' . $artist . ' ' . esc_html( $song_title ) . ''; 51 | 52 | echo ''; 53 | 54 | endif; 55 | } 56 | 57 | } 58 | endif; 59 | 60 | if ( ! function_exists( 'life_entry_footer' ) ) : 61 | /** 62 | * Prints HTML with meta information for the categories, tags and comments. 63 | */ 64 | function life_entry_footer() { 65 | 66 | if ( 'post' === get_post_type() ) { 67 | 68 | life_listening(); 69 | 70 | /* translators: used between list items, there is a space after the comma */ 71 | $tags_list = get_the_tag_list(); 72 | if ( $tags_list && is_single() ) { 73 | /* translators: 1: list of tags. */ 74 | printf( '' . esc_html__( '%1$s', 'life' ) . '', $tags_list ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 75 | } 76 | 77 | } 78 | 79 | edit_post_link( 80 | sprintf( 81 | wp_kses( 82 | /* translators: %s: Name of current post. Only visible to screen readers */ 83 | __( 'Edit %s', 'life' ), 84 | array( 85 | 'span' => array( 86 | 'class' => array(), 87 | ), 88 | ) 89 | ), 90 | wp_kses_post( get_the_title() ) 91 | ), 92 | '', 93 | '' 94 | ); 95 | } 96 | endif; 97 | 98 | if ( ! function_exists( 'life_post_thumbnail' ) ) : 99 | /** 100 | * Displays an optional post thumbnail. 101 | * 102 | * Wraps the post thumbnail in an anchor element on index views, or a div 103 | * element when on single views. 104 | */ 105 | function life_post_thumbnail() { 106 | if ( post_password_required() || is_attachment() || ! has_post_thumbnail() ) { 107 | return; 108 | } 109 | 110 | if ( is_singular() ) : 111 | ?> 112 | 113 | 116 | 117 | 118 | 119 | 122 | 123 | max_num_pages <= 1) return; 138 | 139 | $post_type = get_post_type(); 140 | $post_type_name = get_post_type_object( $post_type )->labels->name; 141 | 142 | $args = wp_parse_args( $args, [ 143 | 'mid_size' => 3, 144 | 'prev_next' => false, 145 | 'next_text' => '' . esc_html__( 'Newer', 'life' ) . ' ' . $post_type_name . '', 146 | 'prev_text' => '' . esc_html__( 'Older', 'life' ) . ' ' . $post_type_name . '', 147 | 'screen_reader_text' => __('Posts Navigation', 'life'), 148 | ]); 149 | 150 | $links = paginate_links($args); 151 | $next_link = get_previous_posts_link( $args['next_text'] ); 152 | $prev_link = get_next_posts_link( $args['prev_text'] ); 153 | 154 | $template = apply_filters( 'life_pagination_template', ' 155 | ', 159 | $args, 160 | $class 161 | ); 162 | 163 | echo sprintf($template, $class, $args['screen_reader_text'], $next_link, $links, $prev_link); 164 | } 165 | endif; 166 | 167 | if ( ! function_exists( 'life_archive_header' ) ) : 168 | /** 169 | * Custom archive headers. 170 | */ 171 | function life_archive_header() { 172 | 173 | if ( 'life_project' === get_post_type() ) : 174 | dynamic_sidebar( 'header-projects' ); 175 | elseif ( 'life_character' === get_post_type() ) : 176 | dynamic_sidebar( 'header-characters' ); 177 | elseif ( 'life_bookmark' === get_post_type() ) : 178 | dynamic_sidebar( 'header-bookmarks' ); 179 | elseif ( 'life_favorite' === get_post_type() ) : 180 | dynamic_sidebar( 'header-favorites' ); 181 | elseif ( is_tag() ) : 182 | echo '

' . single_term_title( '', false ) . '

'; 183 | else : 184 | the_archive_title( '

', '

' ); 185 | endif; 186 | } 187 | endif; 188 | 189 | if ( ! function_exists( 'life_archive_submenu' ) ) : 190 | /** 191 | * Archive submenus. 192 | */ 193 | function life_archive_submenu() { 194 | 195 | if ( 'life_project' === get_post_type() ) : 196 | wp_nav_menu( array( 197 | 'theme_location' => 'menu-projects', 198 | 'menu_id' => 'projects-menu', 199 | 'depth' => 1, 200 | ) ); 201 | elseif ( 'life_bookmark' === get_post_type() ) : 202 | wp_nav_menu( array( 203 | 'theme_location' => 'menu-bookmarks', 204 | 'menu_id' => 'bookmarks-menu', 205 | 'depth' => 1, 206 | ) ); 207 | elseif ( 'life_favorite' === get_post_type() ) : 208 | wp_nav_menu( array( 209 | 'theme_location' => 'menu-favorites', 210 | 'menu_id' => 'favorites-menu', 211 | 'depth' => 1, 212 | ) ); 213 | endif; 214 | } 215 | endif; 216 | 217 | if ( ! function_exists( 'wp_body_open' ) ) : 218 | /** 219 | * Shim for sites older than 5.2. 220 | * 221 | * @link https://core.trac.wordpress.org/ticket/12563 222 | */ 223 | function wp_body_open() { 224 | do_action( 'wp_body_open' ); 225 | } 226 | endif; 227 | -------------------------------------------------------------------------------- /library/sass/generic/_normalize.scss: -------------------------------------------------------------------------------- 1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /* Document 4 | ========================================================================== */ 5 | 6 | /** 7 | * 1. Correct the line height in all browsers. 8 | * 2. Prevent adjustments of font size after orientation changes in iOS. 9 | */ 10 | 11 | html { 12 | line-height: 1.15; 13 | -webkit-text-size-adjust: 100%; 14 | } 15 | 16 | /* Sections 17 | ========================================================================== */ 18 | 19 | /** 20 | * Remove the margin in all browsers. 21 | */ 22 | 23 | body { 24 | margin: 0; 25 | } 26 | 27 | /** 28 | * Render the `main` element consistently in IE. 29 | */ 30 | 31 | main { 32 | display: block; 33 | } 34 | 35 | /** 36 | * Correct the font size and margin on `h1` elements within `section` and 37 | * `article` contexts in Chrome, Firefox, and Safari. 38 | */ 39 | 40 | h1 { 41 | font-size: 2em; 42 | margin: 0.67em 0; 43 | } 44 | 45 | /* Grouping content 46 | ========================================================================== */ 47 | 48 | /** 49 | * 1. Add the correct box sizing in Firefox. 50 | * 2. Show the overflow in Edge and IE. 51 | */ 52 | 53 | hr { 54 | box-sizing: content-box; 55 | height: 0; 56 | overflow: visible; 57 | } 58 | 59 | /** 60 | * 1. Correct the inheritance and scaling of font size in all browsers. 61 | * 2. Correct the odd `em` font sizing in all browsers. 62 | */ 63 | 64 | pre { 65 | font-family: monospace, monospace; 66 | font-size: 1em; 67 | } 68 | 69 | /* Text-level semantics 70 | ========================================================================== */ 71 | 72 | /** 73 | * Remove the gray background on active links in IE 10. 74 | */ 75 | 76 | a { 77 | background-color: transparent; 78 | } 79 | 80 | /** 81 | * 1. Remove the bottom border in Chrome 57- 82 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 83 | */ 84 | 85 | abbr[title] { 86 | border-bottom: none; 87 | text-decoration: underline; 88 | text-decoration: underline dotted; 89 | } 90 | 91 | /** 92 | * Add the correct font weight in Chrome, Edge, and Safari. 93 | */ 94 | 95 | b, 96 | strong { 97 | font-weight: bolder; 98 | } 99 | 100 | /** 101 | * 1. Correct the inheritance and scaling of font size in all browsers. 102 | * 2. Correct the odd `em` font sizing in all browsers. 103 | */ 104 | 105 | code, 106 | kbd, 107 | samp { 108 | font-family: monospace, monospace; 109 | font-size: 1em; 110 | } 111 | 112 | /** 113 | * Add the correct font size in all browsers. 114 | */ 115 | 116 | small { 117 | font-size: 80%; 118 | } 119 | 120 | /** 121 | * Prevent `sub` and `sup` elements from affecting the line height in 122 | * all browsers. 123 | */ 124 | 125 | sub, 126 | sup { 127 | font-size: 75%; 128 | line-height: 0; 129 | position: relative; 130 | vertical-align: baseline; 131 | } 132 | 133 | sub { 134 | bottom: -0.25em; 135 | } 136 | 137 | sup { 138 | top: -0.5em; 139 | } 140 | 141 | /* Embedded content 142 | ========================================================================== */ 143 | 144 | /** 145 | * Remove the border on images inside links in IE 10. 146 | */ 147 | 148 | img { 149 | border-style: none; 150 | } 151 | 152 | /* Forms 153 | ========================================================================== */ 154 | 155 | /** 156 | * 1. Change the font styles in all browsers. 157 | * 2. Remove the margin in Firefox and Safari. 158 | */ 159 | 160 | button, 161 | input, 162 | optgroup, 163 | select, 164 | textarea { 165 | font-family: inherit; 166 | font-size: 100%; 167 | line-height: 1.15; 168 | margin: 0; 169 | } 170 | 171 | /** 172 | * Show the overflow in IE. 173 | * 1. Show the overflow in Edge. 174 | */ 175 | 176 | button, 177 | input { 178 | overflow: visible; 179 | } 180 | 181 | /** 182 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 183 | * 1. Remove the inheritance of text transform in Firefox. 184 | */ 185 | 186 | button, 187 | select { 188 | text-transform: none; 189 | } 190 | 191 | /** 192 | * Correct the inability to style clickable types in iOS and Safari. 193 | */ 194 | 195 | button, 196 | [type="button"], 197 | [type="reset"], 198 | [type="submit"] { 199 | -webkit-appearance: button; 200 | } 201 | 202 | /** 203 | * Remove the inner border and padding in Firefox. 204 | */ 205 | 206 | button::-moz-focus-inner, 207 | [type="button"]::-moz-focus-inner, 208 | [type="reset"]::-moz-focus-inner, 209 | [type="submit"]::-moz-focus-inner { 210 | border-style: none; 211 | padding: 0; 212 | } 213 | 214 | /** 215 | * Restore the focus styles unset by the previous rule. 216 | */ 217 | 218 | button:-moz-focusring, 219 | [type="button"]:-moz-focusring, 220 | [type="reset"]:-moz-focusring, 221 | [type="submit"]:-moz-focusring { 222 | outline: 1px dotted ButtonText; 223 | } 224 | 225 | /** 226 | * Correct the padding in Firefox. 227 | */ 228 | 229 | fieldset { 230 | padding: 0.35em 0.75em 0.625em; 231 | } 232 | 233 | /** 234 | * 1. Correct the text wrapping in Edge and IE. 235 | * 2. Correct the color inheritance from `fieldset` elements in IE. 236 | * 3. Remove the padding so developers are not caught out when they zero out 237 | * `fieldset` elements in all browsers. 238 | */ 239 | 240 | legend { 241 | box-sizing: border-box; 242 | color: inherit; 243 | display: table; 244 | max-width: 100%; 245 | padding: 0; 246 | white-space: normal; 247 | } 248 | 249 | /** 250 | * Add the correct vertical alignment in Chrome, Firefox, and Opera. 251 | */ 252 | 253 | progress { 254 | vertical-align: baseline; 255 | } 256 | 257 | /** 258 | * Remove the default vertical scrollbar in IE 10+. 259 | */ 260 | 261 | textarea { 262 | overflow: auto; 263 | } 264 | 265 | /** 266 | * 1. Add the correct box sizing in IE 10. 267 | * 2. Remove the padding in IE 10. 268 | */ 269 | 270 | [type="checkbox"], 271 | [type="radio"] { 272 | box-sizing: border-box; 273 | padding: 0; 274 | } 275 | 276 | /** 277 | * Correct the cursor style of increment and decrement buttons in Chrome. 278 | */ 279 | 280 | [type="number"]::-webkit-inner-spin-button, 281 | [type="number"]::-webkit-outer-spin-button { 282 | height: auto; 283 | } 284 | 285 | /** 286 | * 1. Correct the odd appearance in Chrome and Safari. 287 | * 2. Correct the outline style in Safari. 288 | */ 289 | 290 | [type="search"] { 291 | -webkit-appearance: textfield; 292 | outline-offset: -2px; 293 | } 294 | 295 | /** 296 | * Remove the inner padding in Chrome and Safari on macOS. 297 | */ 298 | 299 | [type="search"]::-webkit-search-decoration { 300 | -webkit-appearance: none; 301 | } 302 | 303 | /** 304 | * 1. Correct the inability to style clickable types in iOS and Safari. 305 | * 2. Change font properties to `inherit` in Safari. 306 | */ 307 | 308 | ::-webkit-file-upload-button { 309 | -webkit-appearance: button; 310 | font: inherit; 311 | } 312 | 313 | /* Interactive 314 | ========================================================================== */ 315 | 316 | /* 317 | * Add the correct display in Edge, IE 10+, and Firefox. 318 | */ 319 | 320 | details { 321 | display: block; 322 | } 323 | 324 | /* 325 | * Add the correct display in all browsers. 326 | */ 327 | 328 | summary { 329 | display: list-item; 330 | } 331 | 332 | /* Misc 333 | ========================================================================== */ 334 | 335 | /** 336 | * Add the correct display in IE 10+. 337 | */ 338 | 339 | template { 340 | display: none; 341 | } 342 | 343 | /** 344 | * Add the correct display in IE 10. 345 | */ 346 | 347 | [hidden] { 348 | display: none; 349 | } 350 | -------------------------------------------------------------------------------- /library/sass/components/navigation/_header.scss: -------------------------------------------------------------------------------- 1 | 2 | /*-------------------------------------------------------------- 3 | ## Site Header 4 | --------------------------------------------------------------*/ 5 | 6 | .site-header { 7 | background: var(--color__background-alt); 8 | font-family: var(--font__alt); 9 | position: -webkit-sticky; 10 | position: sticky; 11 | top: -1px; 12 | z-index: 9; 13 | 14 | .wrap { 15 | align-items: center; 16 | display: flex; 17 | padding-top: 0.25rem; 18 | padding-bottom: 0.25rem; 19 | 20 | @media screen and ($medium-up) { 21 | padding-top: 0.5rem; 22 | padding-bottom: 0.5rem; 23 | } 24 | } 25 | 26 | a { 27 | letter-spacing: $font__letter-spacing; 28 | text-decoration: none; 29 | text-transform: uppercase; 30 | } 31 | } // .site-header 32 | 33 | .site-title, 34 | .breadcrumb { 35 | font-size: $typesize__small; 36 | letter-spacing: $font__letter-spacing; 37 | margin: 0 1.25rem 0 0; 38 | } 39 | 40 | .site-description { 41 | font-size: $typesize__tiny; 42 | letter-spacing: $font__letter-spacing; 43 | margin: 0 1.25rem 0 0; 44 | text-transform: uppercase; 45 | } 46 | 47 | .breadcrumb a { 48 | color: var(--color__breadcrumb-link); 49 | 50 | &:hover, 51 | &:focus { 52 | color: var(--color__breadcrumb-link-hover); 53 | } 54 | } 55 | 56 | 57 | /*-------------------------------------------------------------- 58 | ## Search Form 59 | --------------------------------------------------------------*/ 60 | 61 | .site-header .search { 62 | 63 | &-form { 64 | position: relative; 65 | 66 | .icon-button { 67 | padding: 0 0.25rem; 68 | position: absolute; 69 | right: 0.5rem; 70 | top: 0; 71 | bottom: 0; 72 | } 73 | 74 | .icon-search { 75 | font-weight: bold; 76 | } 77 | } 78 | 79 | &-field { 80 | background: mix($light, $mediumlight, 60%); 81 | border-color: mix($light, $mediumlight, 60%); 82 | border-radius: 1rem; 83 | font-size: $typesize__small; 84 | line-height: 1; 85 | padding: 0.375rem 1.5rem 0.375rem 1rem; 86 | transition: all 0.125s; 87 | width: 100%; 88 | 89 | &:focus { 90 | outline: none; 91 | } 92 | 93 | &:focus-visible { 94 | border-color: $dark; 95 | } 96 | } 97 | } // .site-header .search 98 | 99 | 100 | /*-------------------------------------------------------------- 101 | ## Main Nav (Drawer) 102 | --------------------------------------------------------------*/ 103 | 104 | .main-navigation { 105 | margin-left: auto; 106 | 107 | .menu { 108 | list-style: none; 109 | margin-bottom: 3rem; 110 | padding-left: 0; 111 | 112 | &-item { 113 | font-size: $typesize__small; 114 | } 115 | } 116 | 117 | a { 118 | color: $light; 119 | display: block; 120 | padding: 0.75rem 2rem; 121 | text-decoration: none; 122 | 123 | &:hover, 124 | &:focus { 125 | background: $black; 126 | } 127 | } 128 | 129 | .menu-item a::before { 130 | display: inline-block; 131 | font-size: $typesize__normal; 132 | text-align: center; 133 | vertical-align: -0.25em; 134 | width: 1.5rem; 135 | } 136 | 137 | .search-form { 138 | margin: 1rem 4rem 2rem 2rem; 139 | 140 | @media screen and ($large-up) { 141 | display: none; 142 | } 143 | } 144 | 145 | .search-field { 146 | background: var(--color__background-alt); 147 | } 148 | 149 | &.toggled { 150 | z-index: 9; 151 | } 152 | 153 | .sub-menu { 154 | margin-left: 0; 155 | padding-left: 0; 156 | 157 | a { 158 | color: $medium; 159 | padding-left: 4rem; 160 | } 161 | } 162 | 163 | @media screen and ($large-up) { 164 | margin-left: 1rem; 165 | } 166 | } // .main-navigation 167 | 168 | .site-header .wrap { 169 | position: relative; 170 | } 171 | 172 | .main-nav-container { 173 | background: rgba($dark, 0.94); 174 | border-bottom-right-radius: 0.5rem; 175 | border-bottom-left-radius: 0.5rem; 176 | max-height: 100vh; 177 | min-width: 16rem; 178 | opacity: 0; 179 | overflow-y: auto; 180 | pointer-events: none; 181 | position: absolute; 182 | right: 0; 183 | top: 0; 184 | transition: all 0.25s ease-out; 185 | width: 100%; 186 | 187 | .toggled & { 188 | opacity: 1; 189 | pointer-events: all; 190 | } 191 | 192 | @media screen and ($small-up) { 193 | width: 20rem; 194 | } 195 | 196 | @media screen and ($large-up) { 197 | padding-top: 3rem; 198 | } 199 | } 200 | 201 | 202 | /*-------------------------------------------------------------- 203 | ## Menu Toggle 204 | --------------------------------------------------------------*/ 205 | 206 | $button-width: 3rem; 207 | $bar-thickness: $button-width * 0.0375; 208 | $bar-thickness-large: $bar-thickness; 209 | $transition-duration: 0.15s; 210 | $bar-color: var(--color__button); 211 | $bar-color-open: $light; 212 | $icon-padding: 0.75rem; 213 | 214 | .menu-toggle { 215 | background: transparent; 216 | box-shadow: 0; 217 | display: block; 218 | float: right; 219 | height: $button-width; 220 | margin-right: -$icon-padding; 221 | position: relative; 222 | width: $button-width; 223 | z-index: 9; 224 | 225 | &:hover, 226 | &:focus, 227 | &:active { 228 | background: transparent; 229 | box-shadow: none; 230 | } 231 | } 232 | 233 | .menu-toggle .icon { 234 | background: $bar-color; // middle-bar 235 | display: block; 236 | height: $bar-thickness; 237 | position: absolute; 238 | top: 1.375rem; 239 | transition: background 0s $transition-duration; 240 | left: $icon-padding; 241 | right: $icon-padding; 242 | 243 | // top and bottom bars 244 | &::before, 245 | &::after { 246 | background-color: $bar-color; 247 | content: ''; 248 | display: block; 249 | height: $bar-thickness; 250 | left: 0; 251 | position: absolute; 252 | transition-duration: $transition-duration, $transition-duration; 253 | transition-delay: $transition-duration, 0s; 254 | width: 100%; 255 | } 256 | 257 | &::before { 258 | top: -0.45rem; 259 | transition-property: top, transform; 260 | } 261 | 262 | &::after { 263 | bottom: -0.45rem; 264 | transition-property: bottom, transform; 265 | } 266 | 267 | .toggled & { 268 | background: none; // remove middle bar 269 | 270 | &::before { 271 | top: 0; 272 | transform: rotate(45deg); 273 | } 274 | 275 | &::after { 276 | bottom: 0; 277 | transform: rotate(-45deg); 278 | } 279 | 280 | &::before, 281 | &::after { 282 | background-color: $bar-color-open; 283 | transition-delay: 0s, $transition-duration; 284 | } 285 | } 286 | 287 | // adjust bar thickness when html base font size goes up 288 | @media screen and ($large-up) { 289 | height: $bar-thickness-large; 290 | 291 | &::before, 292 | &::after { 293 | height: $bar-thickness-large; 294 | } 295 | } 296 | } // .menu-toggle .icon 297 | 298 | 299 | /*-------------------------------------------------------------- 300 | ## Desktop Nav 301 | --------------------------------------------------------------*/ 302 | 303 | .desktop-navigation { 304 | display: none; 305 | border-left: 1px solid var(--color__background-hr); 306 | padding-left: 1rem; 307 | 308 | .menu { 309 | display: flex; 310 | list-style: none; 311 | padding-left: 0; 312 | } 313 | 314 | .menu-item { 315 | margin-right: 1.25rem; 316 | } 317 | 318 | a { 319 | color: var(--color__nav-link); 320 | display: block; 321 | text-decoration: none; 322 | font-size: $typesize__small; 323 | } 324 | 325 | a:hover, 326 | a:focus, 327 | .current_page_item > a, 328 | .current-menu-item > a, 329 | .current_page_ancestor > a, 330 | .current-menu-ancestor > a, 331 | 332 | // highlight menu item for taxonomy pages too 333 | .tag & .menu-item-type-post_type a, // Photos 334 | .date & .menu-item-type-post_type a, // Photos 335 | .tax-life_favorite_type & .menu-item-object-life_favorite a, // Favorites 336 | .tax-life_bookmark_type & .menu-item-object-life_bookmark a, // Bookmarks 337 | .tax-life_collection & .menu-item-object-life_project a { // Projects 338 | color: var(--color__nav-link-hover); 339 | } 340 | 341 | @media screen and ($medium-up) { 342 | display: block; 343 | } 344 | } 345 | 346 | .desktop-search { 347 | display: none; 348 | margin-left: auto; 349 | 350 | @media screen and ($large-up) { 351 | display: block; 352 | } 353 | } 354 | 355 | -------------------------------------------------------------------------------- /languages/lifetheme.pot: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2021 Kay Belardinelli 2 | # This file is distributed under the GNU General Public License v2 or later. 3 | msgid "" 4 | msgstr "" 5 | "Project-Id-Version: Life 1.3.3\n" 6 | "Report-Msgid-Bugs-To: https://wordpress.org/support/theme/life\n" 7 | "Last-Translator: FULL NAME \n" 8 | "Language-Team: LANGUAGE \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "POT-Creation-Date: 2021-05-05T18:24:06+00:00\n" 13 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 | "X-Generator: WP-CLI 2.4.0\n" 15 | "X-Domain: life\n" 16 | 17 | #. Theme Name of the theme 18 | msgid "Life" 19 | msgstr "" 20 | 21 | #. Description of the theme 22 | msgid "Minimalist WordPress theme" 23 | msgstr "" 24 | 25 | #. Author of the theme 26 | msgid "Kay Belardinelli" 27 | msgstr "" 28 | 29 | #. Author URI of the theme 30 | msgid "https://kangabell.co" 31 | msgstr "" 32 | 33 | #: 404.php:22 34 | msgid "This is unfortunate." 35 | msgstr "" 36 | 37 | #: 404.php:26 38 | msgid "The page you are looking for is not in service. You might try using the search box. Additionally you can drop a note and let me know where things went wrong!" 39 | msgstr "" 40 | 41 | #: comments.php:30 42 | msgid "Comments" 43 | msgstr "" 44 | 45 | #: comments.php:50 46 | msgid "Comments are closed." 47 | msgstr "" 48 | 49 | #: comments.php:62 50 | msgid "Submit Reply" 51 | msgstr "" 52 | 53 | #: footer.php:32 54 | msgid "Up" 55 | msgstr "" 56 | 57 | #: functions.php:58 58 | msgid "Primary" 59 | msgstr "" 60 | 61 | #: functions.php:59 62 | msgid "Secondary" 63 | msgstr "" 64 | 65 | #: functions.php:60 66 | msgid "Footer" 67 | msgstr "" 68 | 69 | #: functions.php:106 70 | msgid "Homepage Secondary Content" 71 | msgstr "" 72 | 73 | #: functions.php:108 74 | #: functions.php:117 75 | #: functions.php:126 76 | #: functions.php:135 77 | #: functions.php:144 78 | #: functions.php:153 79 | msgid "Add widgets here." 80 | msgstr "" 81 | 82 | #: functions.php:115 83 | msgid "Posts Header" 84 | msgstr "" 85 | 86 | #: functions.php:124 87 | msgid "Projects Header" 88 | msgstr "" 89 | 90 | #: functions.php:133 91 | msgid "Characters Header" 92 | msgstr "" 93 | 94 | #: functions.php:142 95 | msgid "Links Header" 96 | msgstr "" 97 | 98 | #: functions.php:151 99 | msgid "Favorites Header" 100 | msgstr "" 101 | 102 | #: functions.php:172 103 | msgctxt "taxonomy general name" 104 | msgid "Collections" 105 | msgstr "" 106 | 107 | #: functions.php:173 108 | msgctxt "taxonomy singular name" 109 | msgid "Collection" 110 | msgstr "" 111 | 112 | #: functions.php:174 113 | msgid "Search Collections" 114 | msgstr "" 115 | 116 | #: functions.php:175 117 | msgid "All Collections" 118 | msgstr "" 119 | 120 | #: functions.php:176 121 | msgid "View Collection" 122 | msgstr "" 123 | 124 | #: functions.php:177 125 | msgid "Parent Collection" 126 | msgstr "" 127 | 128 | #: functions.php:178 129 | msgid "Parent Collection:" 130 | msgstr "" 131 | 132 | #: functions.php:179 133 | msgid "Edit Collection" 134 | msgstr "" 135 | 136 | #: functions.php:180 137 | msgid "Update Collection" 138 | msgstr "" 139 | 140 | #: functions.php:181 141 | msgid "Add New Collection" 142 | msgstr "" 143 | 144 | #: functions.php:182 145 | msgid "New Collection Name" 146 | msgstr "" 147 | 148 | #: functions.php:183 149 | msgid "No Collections Found" 150 | msgstr "" 151 | 152 | #: functions.php:184 153 | msgid "Back to Collections" 154 | msgstr "" 155 | 156 | #: functions.php:185 157 | msgid "Collections" 158 | msgstr "" 159 | 160 | #: functions.php:194 161 | msgctxt "taxonomy general name" 162 | msgid "Favorite Types" 163 | msgstr "" 164 | 165 | #: functions.php:195 166 | #: functions.php:217 167 | msgctxt "taxonomy singular name" 168 | msgid "Type" 169 | msgstr "" 170 | 171 | #: functions.php:196 172 | #: functions.php:218 173 | msgid "Search Types" 174 | msgstr "" 175 | 176 | #: functions.php:197 177 | #: functions.php:219 178 | msgid "All Types" 179 | msgstr "" 180 | 181 | #: functions.php:198 182 | #: functions.php:220 183 | msgid "View Type" 184 | msgstr "" 185 | 186 | #: functions.php:199 187 | #: functions.php:221 188 | msgid "Parent Type" 189 | msgstr "" 190 | 191 | #: functions.php:200 192 | #: functions.php:222 193 | msgid "Parent Type:" 194 | msgstr "" 195 | 196 | #: functions.php:201 197 | #: functions.php:223 198 | msgid "Edit Type" 199 | msgstr "" 200 | 201 | #: functions.php:202 202 | #: functions.php:224 203 | msgid "Update Type" 204 | msgstr "" 205 | 206 | #: functions.php:203 207 | #: functions.php:225 208 | msgid "Add New Type" 209 | msgstr "" 210 | 211 | #: functions.php:204 212 | #: functions.php:226 213 | msgid "New Type Name" 214 | msgstr "" 215 | 216 | #: functions.php:205 217 | #: functions.php:227 218 | msgid "No Types Found" 219 | msgstr "" 220 | 221 | #: functions.php:206 222 | #: functions.php:228 223 | msgid "Back to Types" 224 | msgstr "" 225 | 226 | #: functions.php:207 227 | #: functions.php:229 228 | msgid "Types" 229 | msgstr "" 230 | 231 | #: functions.php:216 232 | msgctxt "taxonomy general name" 233 | msgid "Link Types" 234 | msgstr "" 235 | 236 | #: functions.php:248 237 | msgctxt "Post type general name" 238 | msgid "Projects" 239 | msgstr "" 240 | 241 | #: functions.php:249 242 | msgctxt "Post type singular name" 243 | msgid "Project" 244 | msgstr "" 245 | 246 | #: functions.php:250 247 | msgctxt "Admin Menu text" 248 | msgid "Projects" 249 | msgstr "" 250 | 251 | #: functions.php:251 252 | msgctxt "Add New on Toolbar" 253 | msgid "Project" 254 | msgstr "" 255 | 256 | #: functions.php:252 257 | #: functions.php:280 258 | #: functions.php:308 259 | #: functions.php:336 260 | msgid "Add New" 261 | msgstr "" 262 | 263 | #: functions.php:253 264 | msgid "Add New Project" 265 | msgstr "" 266 | 267 | #: functions.php:254 268 | msgid "New Project" 269 | msgstr "" 270 | 271 | #: functions.php:255 272 | msgid "Edit Project" 273 | msgstr "" 274 | 275 | #: functions.php:256 276 | msgid "View Project" 277 | msgstr "" 278 | 279 | #: functions.php:257 280 | msgid "All Projects" 281 | msgstr "" 282 | 283 | #: functions.php:258 284 | msgid "Search Projects" 285 | msgstr "" 286 | 287 | #: functions.php:259 288 | msgid "Parent Projects:" 289 | msgstr "" 290 | 291 | #: functions.php:260 292 | msgid "No projects found." 293 | msgstr "" 294 | 295 | #: functions.php:261 296 | msgid "No projects found in Trash." 297 | msgstr "" 298 | 299 | #: functions.php:276 300 | msgctxt "Post type general name" 301 | msgid "Characters" 302 | msgstr "" 303 | 304 | #: functions.php:277 305 | msgctxt "Post type singular name" 306 | msgid "Character" 307 | msgstr "" 308 | 309 | #: functions.php:278 310 | msgctxt "Admin Menu text" 311 | msgid "Characters" 312 | msgstr "" 313 | 314 | #: functions.php:279 315 | msgctxt "Add New on Toolbar" 316 | msgid "Character" 317 | msgstr "" 318 | 319 | #: functions.php:281 320 | msgid "Add New Character" 321 | msgstr "" 322 | 323 | #: functions.php:282 324 | msgid "New Character" 325 | msgstr "" 326 | 327 | #: functions.php:283 328 | msgid "Edit Character" 329 | msgstr "" 330 | 331 | #: functions.php:284 332 | msgid "View Character" 333 | msgstr "" 334 | 335 | #: functions.php:285 336 | msgid "All Characters" 337 | msgstr "" 338 | 339 | #: functions.php:286 340 | msgid "Search Characters" 341 | msgstr "" 342 | 343 | #: functions.php:287 344 | msgid "Parent Characters:" 345 | msgstr "" 346 | 347 | #: functions.php:288 348 | msgid "No characters found." 349 | msgstr "" 350 | 351 | #: functions.php:289 352 | msgid "No characters found in Trash." 353 | msgstr "" 354 | 355 | #: functions.php:304 356 | msgctxt "Post type general name" 357 | msgid "Favorites" 358 | msgstr "" 359 | 360 | #: functions.php:305 361 | msgctxt "Post type singular name" 362 | msgid "Favorite" 363 | msgstr "" 364 | 365 | #: functions.php:306 366 | msgctxt "Admin Menu text" 367 | msgid "Favorites" 368 | msgstr "" 369 | 370 | #: functions.php:307 371 | msgctxt "Add New on Toolbar" 372 | msgid "Favorite" 373 | msgstr "" 374 | 375 | #: functions.php:309 376 | msgid "Add New Favorite" 377 | msgstr "" 378 | 379 | #: functions.php:310 380 | msgid "New Favorite" 381 | msgstr "" 382 | 383 | #: functions.php:311 384 | msgid "Edit Favorite" 385 | msgstr "" 386 | 387 | #: functions.php:312 388 | msgid "View Favorite" 389 | msgstr "" 390 | 391 | #: functions.php:313 392 | msgid "All Favorites" 393 | msgstr "" 394 | 395 | #: functions.php:314 396 | msgid "Search Favorites" 397 | msgstr "" 398 | 399 | #: functions.php:315 400 | msgid "Parent Favorites:" 401 | msgstr "" 402 | 403 | #: functions.php:316 404 | msgid "No favorites found." 405 | msgstr "" 406 | 407 | #: functions.php:317 408 | msgid "No favorites found in Trash." 409 | msgstr "" 410 | 411 | #: functions.php:332 412 | msgctxt "Post type general name" 413 | msgid "Links" 414 | msgstr "" 415 | 416 | #: functions.php:333 417 | msgctxt "Post type singular name" 418 | msgid "Link" 419 | msgstr "" 420 | 421 | #: functions.php:334 422 | msgctxt "Admin Menu text" 423 | msgid "Links" 424 | msgstr "" 425 | 426 | #: functions.php:335 427 | msgctxt "Add New on Toolbar" 428 | msgid "Link" 429 | msgstr "" 430 | 431 | #: functions.php:337 432 | msgid "Add New Link" 433 | msgstr "" 434 | 435 | #: functions.php:338 436 | msgid "New Link" 437 | msgstr "" 438 | 439 | #: functions.php:339 440 | msgid "Edit Link" 441 | msgstr "" 442 | 443 | #: functions.php:340 444 | msgid "View Link" 445 | msgstr "" 446 | 447 | #: functions.php:341 448 | msgid "All Links" 449 | msgstr "" 450 | 451 | #: functions.php:342 452 | msgid "Search Links" 453 | msgstr "" 454 | 455 | #: functions.php:343 456 | msgid "Parent Links:" 457 | msgstr "" 458 | 459 | #: functions.php:344 460 | msgid "No links found." 461 | msgstr "" 462 | 463 | #: functions.php:345 464 | msgid "No links found in Trash." 465 | msgstr "" 466 | 467 | #: header.php:26 468 | msgid "Skip to content" 469 | msgstr "" 470 | 471 | #: header.php:80 472 | msgid "Menu" 473 | msgstr "" 474 | 475 | #: inc/customizer.php:47 476 | msgid "Subfooter" 477 | msgstr "" 478 | 479 | #: inc/customizer.php:63 480 | msgid "Link Color" 481 | msgstr "" 482 | 483 | #: inc/template-tags.php:49 484 | msgid "Currently Listening" 485 | msgstr "" 486 | 487 | #. translators: 1: list of tags. 488 | #: inc/template-tags.php:57 489 | msgid "%1$s" 490 | msgstr "" 491 | 492 | #. translators: %s: Name of current post. Only visible to screen readers 493 | #: inc/template-tags.php:66 494 | #: template-parts/content-page.php:46 495 | msgid "Edit %s" 496 | msgstr "" 497 | 498 | #: inc/template-tags.php:127 499 | msgid "Posts Navigation" 500 | msgstr "" 501 | 502 | #: searchform.php:6 503 | msgid "Submit" 504 | msgstr "" 505 | 506 | #: single.php:36 507 | msgid "View All " 508 | msgstr "" 509 | 510 | #: template-parts/card.php:15 511 | #: template-parts/thumbnail.php:7 512 | msgid "Image Missing" 513 | msgstr "" 514 | 515 | #: template-parts/content-none.php:14 516 | msgid "Nothing Found" 517 | msgstr "" 518 | 519 | #. translators: 1: link to WP admin new post page. 520 | #: template-parts/content-none.php:24 521 | msgid "Ready to publish your first post? Get started here." 522 | msgstr "" 523 | 524 | #: template-parts/content-none.php:37 525 | msgid "Sorry, but nothing matched your search terms. Please try again!" 526 | msgstr "" 527 | 528 | #: template-parts/content-none.php:43 529 | msgid "It seems we can’t find what you’re looking for." 530 | msgstr "" 531 | 532 | #: template-parts/content-page.php:32 533 | #: template-parts/content.php:62 534 | msgid "Pages:" 535 | msgstr "" 536 | 537 | #. translators: %s: Name of current post. Only visible to screen readers 538 | #: template-parts/content.php:49 539 | msgid "Continue reading \"%s\"" 540 | msgstr "" 541 | 542 | #: template-parts/content.php:83 543 | msgid "Posts with " 544 | msgstr "" 545 | 546 | #: template-parts/content.php:99 547 | msgid "Cohorts" 548 | msgstr "" 549 | 550 | #: template-parts/content.php:101 551 | msgid "Cast of Characters" 552 | msgstr "" 553 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /functions.php: -------------------------------------------------------------------------------- 1 | tag in the document head, and expect WordPress to 36 | * provide it for us. 37 | */ 38 | add_theme_support( 'title-tag' ); 39 | 40 | /* 41 | * Enable support for Post Thumbnails on posts and pages 42 | * 43 | * @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/ 44 | */ 45 | add_theme_support( 'post-thumbnails' ); 46 | 47 | /* 48 | * Add custom image size for Post Thumbnails 49 | * 50 | * @link https://developer.wordpress.org/reference/functions/add_image_size/ 51 | */ 52 | add_image_size( 'medium_square', 570, 570, true ); 53 | add_image_size( 'small_square', 345, 345, true ); 54 | 55 | /* 56 | * Add theme support for wide alignment blocks 57 | * 58 | * @link https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-support/#wide-alignment 59 | */ 60 | add_theme_support( 'align-wide' ); 61 | 62 | // This theme uses wp_nav_menu() in one location. 63 | register_nav_menus( 64 | array( 65 | 'menu-1' => esc_html__( 'Primary', 'life' ), 66 | 'menu-2' => esc_html__( 'Secondary', 'life' ), 67 | 'menu-3' => esc_html__( 'Footer', 'life' ), 68 | 'menu-projects' => esc_html__( 'Projects Submenu', 'life' ), 69 | 'menu-bookmarks' => esc_html__( 'Links Submenu', 'life' ), 70 | 'menu-favorites' => esc_html__( 'Favorites Submenu', 'life' ), 71 | ) 72 | ); 73 | 74 | /* 75 | * Switch default core markup for search form, comment form, and comments 76 | * to output valid HTML5. 77 | */ 78 | add_theme_support( 79 | 'html5', 80 | array( 81 | 'search-form', 82 | 'comment-form', 83 | 'comment-list', 84 | 'gallery', 85 | 'caption', 86 | 'style', 87 | 'script', 88 | ) 89 | ); 90 | 91 | // Add theme support for selective refresh for widgets. 92 | add_theme_support( 'customize-selective-refresh-widgets' ); 93 | } 94 | add_action( 'after_setup_theme', 'life_setup' ); 95 | 96 | /** 97 | * Set the content width in pixels, based on the theme's design and stylesheet. 98 | * 99 | * Priority 0 to make it available to lower priority callbacks. 100 | * 101 | * @global int $content_width 102 | */ 103 | function life_content_width() { 104 | $GLOBALS['content_width'] = apply_filters( 'life_content_width', 640 ); 105 | } 106 | add_action( 'after_setup_theme', 'life_content_width', 0 ); 107 | 108 | 109 | /** 110 | * Register widget area. 111 | * 112 | * @link https://developer.wordpress.org/themes/functionality/sidebars/#registering-a-sidebar 113 | */ 114 | function life_widgets_init() { 115 | register_sidebar( array( 116 | 'name' => esc_html__( 'Homepage Secondary Content', 'life' ), 117 | 'id' => 'home-secondary', 118 | 'description' => esc_html__( 'Add blocks to the bottom of the homepage.', 'life' ), 119 | 'before_title' => '', 120 | 'after_title' => '', 121 | 'before_widget' => '
', 122 | 'after_widget' => '
', 123 | ) ); 124 | register_sidebar( array( 125 | 'name' => esc_html__( 'Blog Header', 'life' ), 126 | 'id' => 'header-posts', 127 | 'description' => esc_html__( 'Add blocks to the top of the blog page.', 'life' ), 128 | 'before_title' => '

', 129 | 'after_title' => '

', 130 | 'before_widget' => '
', 131 | 'after_widget' => '
', 132 | ) ); 133 | register_sidebar( array( 134 | 'name' => esc_html__( 'Posts Secondary Content', 'life' ), 135 | 'id' => 'post-secondary', 136 | 'description' => esc_html__( 'Add blocks to the bottom of the Posts page.', 'life' ), 137 | 'before_title' => '', 138 | 'after_title' => '', 139 | 'before_widget' => '
', 140 | 'after_widget' => '
', 141 | ) ); 142 | register_sidebar( array( 143 | 'name' => esc_html__( 'Projects Header', 'life' ), 144 | 'id' => 'header-projects', 145 | 'description' => esc_html__( 'Add blocks to the top of the Projects page.', 'life' ), 146 | 'before_title' => '

', 147 | 'after_title' => '

', 148 | 'before_widget' => '
', 149 | 'after_widget' => '
', 150 | ) ); 151 | register_sidebar( array( 152 | 'name' => esc_html__( 'Characters Header', 'life' ), 153 | 'id' => 'header-characters', 154 | 'description' => esc_html__( 'Add blocks to the top of the Characters page.', 'life' ), 155 | 'before_title' => '

', 156 | 'after_title' => '

', 157 | 'before_widget' => '
', 158 | 'after_widget' => '
', 159 | ) ); 160 | register_sidebar( array( 161 | 'name' => esc_html__( 'Links Header', 'life' ), 162 | 'id' => 'header-bookmarks', 163 | 'description' => esc_html__( 'Add blocks to the top of the Links page.', 'life' ), 164 | 'before_title' => '

', 165 | 'after_title' => '

', 166 | 'before_widget' => '
', 167 | 'after_widget' => '
', 168 | ) ); 169 | register_sidebar( array( 170 | 'name' => esc_html__( 'Links Archive Secondary Content', 'life' ), 171 | 'id' => 'bookmarks-secondary', 172 | 'description' => esc_html__( 'Add blocks to the bottom of the Links and Link Type archive pages.', 'life' ), 173 | 'before_title' => '', 174 | 'after_title' => '', 175 | 'before_widget' => '
', 176 | 'after_widget' => '
', 177 | ) ); 178 | register_sidebar( array( 179 | 'name' => esc_html__( 'Favorites Header', 'life' ), 180 | 'id' => 'header-favorites', 181 | 'description' => esc_html__( 'Add blocks to the top of the Favorites page.', 'life' ), 182 | 'before_title' => '

', 183 | 'after_title' => '

', 184 | 'before_widget' => '
', 185 | 'after_widget' => '
', 186 | ) ); 187 | } 188 | add_action( 'widgets_init', 'life_widgets_init' ); 189 | 190 | 191 | /** 192 | * Register custom taxonomies 193 | * 194 | * @link https://developer.wordpress.org/reference/functions/register_taxonomy/ 195 | */ 196 | function life_custom_taxonomies() { 197 | 198 | register_taxonomy( 'life_collection', 'life_project', array( 199 | 'labels' => array( 200 | 'name' => _x( 'Collections', 'taxonomy general name', 'life' ), 201 | 'singular_name' => _x( 'Collection', 'taxonomy singular name', 'life' ), 202 | 'search_items' => __( 'Search Collections', 'life' ), 203 | 'all_items' => __( 'All Collections', 'life' ), 204 | 'view_item' => __( 'View Collection', 'life' ), 205 | 'parent_item' => __( 'Parent Collection', 'life' ), 206 | 'parent_item_colon' => __( 'Parent Collection:', 'life' ), 207 | 'edit_item' => __( 'Edit Collection', 'life' ), 208 | 'update_item' => __( 'Update Collection', 'life' ), 209 | 'add_new_item' => __( 'Add New Collection', 'life' ), 210 | 'new_item_name' => __( 'New Collection Name', 'life' ), 211 | 'not_found' => __( 'No Collections Found', 'life' ), 212 | 'back_to_items' => __( 'Back to Collections', 'life' ), 213 | 'menu_name' => __( 'Collections', 'life' ), 214 | ), 215 | 'rewrite' => array( 'slug' => 'projects/collection'), 216 | 'hierarchical' => true, 217 | 'show_in_rest' => true, 218 | ) ); 219 | 220 | register_taxonomy( 'life_favorite_type', 'life_favorite', array( 221 | 'labels' => array( 222 | 'name' => _x( 'Favorite Types', 'taxonomy general name', 'life' ), 223 | 'singular_name' => _x( 'Type', 'taxonomy singular name', 'life' ), 224 | 'search_items' => __( 'Search Types', 'life' ), 225 | 'all_items' => __( 'All Types', 'life' ), 226 | 'view_item' => __( 'View Type', 'life' ), 227 | 'parent_item' => __( 'Parent Type', 'life' ), 228 | 'parent_item_colon' => __( 'Parent Type:', 'life' ), 229 | 'edit_item' => __( 'Edit Type', 'life' ), 230 | 'update_item' => __( 'Update Type', 'life' ), 231 | 'add_new_item' => __( 'Add New Type', 'life' ), 232 | 'new_item_name' => __( 'New Type Name', 'life' ), 233 | 'not_found' => __( 'No Types Found', 'life' ), 234 | 'back_to_items' => __( 'Back to Types', 'life' ), 235 | 'menu_name' => __( 'Types', 'life' ), 236 | ), 237 | 'rewrite' => array( 'slug' => 'favorites/type'), 238 | 'hierarchical' => true, 239 | 'show_in_rest' => true, 240 | ) ); 241 | 242 | register_taxonomy( 'life_bookmark_type', 'life_bookmark', array( 243 | 'labels' => array( 244 | 'name' => _x( 'Link Types', 'taxonomy general name', 'life' ), 245 | 'singular_name' => _x( 'Type', 'taxonomy singular name', 'life' ), 246 | 'search_items' => __( 'Search Types', 'life' ), 247 | 'all_items' => __( 'All Types', 'life' ), 248 | 'view_item' => __( 'View Type', 'life' ), 249 | 'parent_item' => __( 'Parent Type', 'life' ), 250 | 'parent_item_colon' => __( 'Parent Type:', 'life' ), 251 | 'edit_item' => __( 'Edit Type', 'life' ), 252 | 'update_item' => __( 'Update Type', 'life' ), 253 | 'add_new_item' => __( 'Add New Type', 'life' ), 254 | 'new_item_name' => __( 'New Type Name', 'life' ), 255 | 'not_found' => __( 'No Types Found', 'life' ), 256 | 'back_to_items' => __( 'Back to Types', 'life' ), 257 | 'menu_name' => __( 'Types', 'life' ), 258 | ), 259 | 'rewrite' => array( 'slug' => 'links/type'), 260 | 'hierarchical' => true, 261 | 'show_in_rest' => true, 262 | ) ); 263 | } 264 | add_action( 'init', 'life_custom_taxonomies', 0 ); 265 | 266 | /** 267 | * Register custom post types 268 | * 269 | * @link https://developer.wordpress.org/plugins/post-types/registering-custom-post-types 270 | */ 271 | function life_custom_post_types() { 272 | 273 | register_post_type('life_project', 274 | array( 275 | 'labels' => array( 276 | 'name' => _x( 'Projects', 'Post type general name', 'life' ), 277 | 'singular_name' => _x( 'Project', 'Post type singular name', 'life' ), 278 | 'menu_name' => _x( 'Projects', 'Admin Menu text', 'life' ), 279 | 'name_admin_bar' => _x( 'Project', 'Add New on Toolbar', 'life' ), 280 | 'add_new' => __( 'Add New', 'life' ), 281 | 'add_new_item' => __( 'Add New Project', 'life' ), 282 | 'new_item' => __( 'New Project', 'life' ), 283 | 'edit_item' => __( 'Edit Project', 'life' ), 284 | 'view_item' => __( 'View Project', 'life' ), 285 | 'all_items' => __( 'All Projects', 'life' ), 286 | 'search_items' => __( 'Search Projects', 'life' ), 287 | 'parent_item_colon' => __( 'Parent Projects:', 'life' ), 288 | 'not_found' => __( 'No projects found.', 'life' ), 289 | 'not_found_in_trash' => __( 'No projects found in Trash.', 'life' ), 290 | ), 291 | 'public' => true, 292 | 'has_archive' => true, 293 | 'rewrite' => array( 'slug' => 'projects'), 294 | 'menu_position' => 4, 295 | 'menu_icon' => 'dashicons-hammer', 296 | 'supports' => array( 'title', 'editor', 'revisions', 'excerpt', 'thumbnail' ), 297 | 'show_in_rest' => true, 298 | ) 299 | ); 300 | 301 | register_post_type('life_character', 302 | array( 303 | 'labels' => array( 304 | 'name' => _x( 'Characters', 'Post type general name', 'life' ), 305 | 'singular_name' => _x( 'Character', 'Post type singular name', 'life' ), 306 | 'menu_name' => _x( 'Characters', 'Admin Menu text', 'life' ), 307 | 'name_admin_bar' => _x( 'Character', 'Add New on Toolbar', 'life' ), 308 | 'add_new' => __( 'Add New', 'life' ), 309 | 'add_new_item' => __( 'Add New Character', 'life' ), 310 | 'new_item' => __( 'New Character', 'life' ), 311 | 'edit_item' => __( 'Edit Character', 'life' ), 312 | 'view_item' => __( 'View Character', 'life' ), 313 | 'all_items' => __( 'All Characters', 'life' ), 314 | 'search_items' => __( 'Search Characters', 'life' ), 315 | 'parent_item_colon' => __( 'Parent Characters:', 'life' ), 316 | 'not_found' => __( 'No characters found.', 'life' ), 317 | 'not_found_in_trash' => __( 'No characters found in Trash.', 'life' ), 318 | ), 319 | 'public' => true, 320 | 'has_archive' => true, 321 | 'rewrite' => array( 'slug' => 'characters'), 322 | 'menu_position' => 5, 323 | 'menu_icon' => 'dashicons-smiley', 324 | 'supports' => array( 'title', 'editor', 'revisions', 'thumbnail' ), 325 | 'show_in_rest' => true, 326 | ) 327 | ); 328 | 329 | register_post_type('life_favorite', 330 | array( 331 | 'labels' => array( 332 | 'name' => _x( 'Favorites', 'Post type general name', 'life' ), 333 | 'singular_name' => _x( 'Favorite', 'Post type singular name', 'life' ), 334 | 'menu_name' => _x( 'Favorites', 'Admin Menu text', 'life' ), 335 | 'name_admin_bar' => _x( 'Favorite', 'Add New on Toolbar', 'life' ), 336 | 'add_new' => __( 'Add New', 'life' ), 337 | 'add_new_item' => __( 'Add New Favorite', 'life' ), 338 | 'new_item' => __( 'New Favorite', 'life' ), 339 | 'edit_item' => __( 'Edit Favorite', 'life' ), 340 | 'view_item' => __( 'View Favorite', 'life' ), 341 | 'all_items' => __( 'All Favorites', 'life' ), 342 | 'search_items' => __( 'Search Favorites', 'life' ), 343 | 'parent_item_colon' => __( 'Parent Favorites:', 'life' ), 344 | 'not_found' => __( 'No favorites found.', 'life' ), 345 | 'not_found_in_trash' => __( 'No favorites found in Trash.', 'life' ), 346 | ), 347 | 'public' => true, 348 | 'has_archive' => true, 349 | 'rewrite' => array( 'slug' => 'favorites'), 350 | 'menu_position' => 6, 351 | 'menu_icon' => 'dashicons-star-filled', 352 | 'supports' => array( 'title', 'editor', 'revisions', 'thumbnail' ), 353 | 'show_in_rest' => true, 354 | ) 355 | ); 356 | 357 | register_post_type('life_bookmark', 358 | array( 359 | 'labels' => array( 360 | 'name' => _x( 'Links', 'Post type general name', 'life' ), 361 | 'singular_name' => _x( 'Link', 'Post type singular name', 'life' ), 362 | 'menu_name' => _x( 'Links', 'Admin Menu text', 'life' ), 363 | 'name_admin_bar' => _x( 'Link', 'Add New on Toolbar', 'life' ), 364 | 'add_new' => __( 'Add New', 'life' ), 365 | 'add_new_item' => __( 'Add New Link', 'life' ), 366 | 'new_item' => __( 'New Link', 'life' ), 367 | 'edit_item' => __( 'Edit Link', 'life' ), 368 | 'view_item' => __( 'View Link', 'life' ), 369 | 'all_items' => __( 'All Links', 'life' ), 370 | 'search_items' => __( 'Search Links', 'life' ), 371 | 'parent_item_colon' => __( 'Parent Links:', 'life' ), 372 | 'not_found' => __( 'No links found.', 'life' ), 373 | 'not_found_in_trash' => __( 'No links found in Trash.', 'life' ), 374 | ), 375 | 'public' => true, 376 | 'has_archive' => true, 377 | 'rewrite' => array( 'slug' => 'links'), 378 | 'menu_position' => 7, 379 | 'menu_icon' => 'dashicons-external', 380 | 'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail' ), 381 | 'show_in_rest' => true, 382 | ) 383 | ); 384 | } 385 | add_action('init', 'life_custom_post_types'); 386 | 387 | /** 388 | * Meta box for Bookmark/Link post type. 389 | */ 390 | require get_template_directory() . '/inc/bookmarks-meta.php'; 391 | 392 | /** 393 | * Enqueue scripts and styles. 394 | */ 395 | function life_scripts() { 396 | wp_enqueue_style( 'life-style', get_template_directory_uri() . '/library/css/style.css', array(), LIFE_VERSION ); 397 | wp_style_add_data( 'life-style', 'rtl', 'replace' ); 398 | 399 | wp_enqueue_script( 'life-navigation', get_template_directory_uri() . '/library/js/navigation.js', array( 'jquery' ), LIFE_VERSION, true ); 400 | 401 | if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) { 402 | wp_enqueue_script( 'comment-reply' ); 403 | } 404 | } 405 | add_action( 'wp_enqueue_scripts', 'life_scripts' ); 406 | 407 | /** 408 | * Enqueue custom admin styles. 409 | */ 410 | function life_admin_scripts() { 411 | wp_enqueue_style( 'life-admin-style', get_template_directory_uri() . '/library/css/admin.css', array(), LIFE_VERSION ); 412 | } 413 | add_action( 'admin_enqueue_scripts', 'life_admin_scripts' ); 414 | 415 | 416 | /** 417 | * Add block editor scripts and styles 418 | */ 419 | function life_gutenberg_scripts() { 420 | 421 | wp_enqueue_style( 'life-editor-style', get_template_directory_uri() . '/library/css/editor.css' ); 422 | 423 | wp_enqueue_script( 424 | 'life-editor-script', 425 | get_template_directory_uri() . '/library/js/editor.js', 426 | array( 'wp-blocks', 'wp-dom' ), 427 | filemtime( get_template_directory() . '/library/js/editor.js' ), 428 | true 429 | ); 430 | } 431 | add_action( 'enqueue_block_editor_assets', 'life_gutenberg_scripts' ); 432 | 433 | /** 434 | * Show only 12 posts for the blog page 435 | */ 436 | function life_home_pagesize( $query ) { 437 | if ( ! is_admin() && $query->is_main_query() && is_home() ) { 438 | $query->set( 'posts_per_page', 12 ); 439 | return; 440 | } 441 | } 442 | add_action( 'pre_get_posts', 'life_home_pagesize', 1 ); 443 | 444 | 445 | /** 446 | * Order date archives (year, month, day) chronologically (not reverse chronological) 447 | */ 448 | function life_date_archives_order( $query ) { 449 | if ( !is_admin() && $query->is_main_query() ) { 450 | 451 | if ( is_date() ) { 452 | $query->set( 'order', 'ASC' ); 453 | } 454 | 455 | return; 456 | } 457 | } 458 | add_action( 'pre_get_posts', 'life_date_archives_order', 1 ); 459 | 460 | /** 461 | * Implement the Custom Header feature. 462 | */ 463 | require get_template_directory() . '/inc/custom-header.php'; 464 | 465 | /** 466 | * Custom template tags for this theme. 467 | */ 468 | require get_template_directory() . '/inc/template-tags.php'; 469 | 470 | /** 471 | * Functions which enhance the theme by hooking into WordPress. 472 | */ 473 | require get_template_directory() . '/inc/template-functions.php'; 474 | 475 | /** 476 | * Customizer additions. 477 | */ 478 | require get_template_directory() . '/inc/customizer.php'; 479 | 480 | /** 481 | * Load Jetpack compatibility file. 482 | */ 483 | if ( defined( 'JETPACK__VERSION' ) ) { 484 | require get_template_directory() . '/inc/jetpack.php'; 485 | } 486 | 487 | /** 488 | * Load WooCommerce compatibility file. 489 | */ 490 | if ( class_exists( 'WooCommerce' ) ) { 491 | require get_template_directory() . '/inc/woocommerce.php'; 492 | } 493 | --------------------------------------------------------------------------------