From 82e1fe563e37dba2ca5d754791b66fd232cbd676 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Fri, 15 Nov 2019 13:17:22 +0100 Subject: [PATCH] Add tagging to system --- .../BackendLayouts/BlogPost.tsconfig | 12 +++- .../PageTSconfig/Tceform/TtContent.tsconfig | 10 ++++ Configuration/TCA/Overrides/sys_category.php | 32 +++++++++++ .../ContentElements/MenuAbstract.typoscript | 46 +++++++++++++++ .../TypoScript/Setup/Page.typoscript | 38 ++++++++++--- .../Layouts/ContentElements/Default.html | 10 ++-- .../Private/Partials/BlogPostHeader.html | 20 +++++++ .../Partials/ContentElements/Header.html | 8 +++ Resources/Private/Partials/Menu/Page.html | 12 ++-- Resources/Private/Partials/TagList.html | 16 ++++++ .../Sass/layout/pages/_singleBlogPost.scss | 5 ++ .../ContentElements/MenuAbstract.html | 13 +++-- .../Private/Templates/Page/BlogPost.html | 56 ++++++++++--------- Resources/Private/Templates/Page/Default.html | 38 +++---------- Resources/Public/Css/index.css | 2 +- ext_tables.sql | 3 + 16 files changed, 238 insertions(+), 83 deletions(-) create mode 100644 Configuration/TCA/Overrides/sys_category.php create mode 100644 Resources/Private/Partials/BlogPostHeader.html create mode 100644 Resources/Private/Partials/ContentElements/Header.html create mode 100644 Resources/Private/Partials/TagList.html create mode 100644 ext_tables.sql diff --git a/Configuration/PageTSconfig/Mod/WebLayout/BackendLayouts/BlogPost.tsconfig b/Configuration/PageTSconfig/Mod/WebLayout/BackendLayouts/BlogPost.tsconfig index 70e9155..0f32ec5 100644 --- a/Configuration/PageTSconfig/Mod/WebLayout/BackendLayouts/BlogPost.tsconfig +++ b/Configuration/PageTSconfig/Mod/WebLayout/BackendLayouts/BlogPost.tsconfig @@ -5,7 +5,7 @@ mod.web_layout.BackendLayouts { config { backend_layout { colCount = 1 - rowCount = 2 + rowCount = 4 rows { 1 { columns { @@ -26,11 +26,19 @@ mod.web_layout.BackendLayouts { 3 { columns { 1 { - name = Footer + name = Acknowledgements colPos = 100 } } } + 4 { + columns { + 1 { + name = Further reading + colPos = 200 + } + } + } } } } diff --git a/Configuration/PageTSconfig/Tceform/TtContent.tsconfig b/Configuration/PageTSconfig/Tceform/TtContent.tsconfig index a29e067..4af4200 100644 --- a/Configuration/PageTSconfig/Tceform/TtContent.tsconfig +++ b/Configuration/PageTSconfig/Tceform/TtContent.tsconfig @@ -14,6 +14,16 @@ TCEFORM.tt_content { layout { disabled = 1 + keepItems := addToList(0) + + types { + menu_abstract { + disabled = 0 + addItems { + 100 = Filtered + } + } + } } frame_class { disabled = 1 diff --git a/Configuration/TCA/Overrides/sys_category.php b/Configuration/TCA/Overrides/sys_category.php new file mode 100644 index 0000000..23aa6fd --- /dev/null +++ b/Configuration/TCA/Overrides/sys_category.php @@ -0,0 +1,32 @@ + [ + 'slug' => [ + 'label' => '.slug', + 'exclude' => 1, + 'config' => [ + 'type' => 'slug', + 'generatorOptions' => [ + 'fields' => ['title'], + 'prefixParentPageSlug' => true, + 'replacements' => [ + '/' => '', + ], + ], + 'fallbackCharacter' => '-', + 'eval' => 'uniqueInSite', + 'default' => '' + ], + ], + ], + ]); + + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes( + $tableName, + 'slug', + '', + 'after:title' + ); +})('sys_category'); diff --git a/Configuration/TypoScript/Setup/ContentElements/MenuAbstract.typoscript b/Configuration/TypoScript/Setup/ContentElements/MenuAbstract.typoscript index 65114c9..851a475 100644 --- a/Configuration/TypoScript/Setup/ContentElements/MenuAbstract.typoscript +++ b/Configuration/TypoScript/Setup/ContentElements/MenuAbstract.typoscript @@ -4,8 +4,54 @@ tt_content.menu_abstract { dataProcessing { 10 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor 10 { + if { + value = 0 + equals.field = layout + } special = directory special.value.field = pages + dataProcessing { + 10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor + 10 { + selectFields = sys_category.* + table = sys_category + pidInList = 2 + where = sys_category_record_mm.uid_foreign = {field:uid} AND sys_category.parent = 2 + where.insertData = 1 + leftjoin = sys_category_record_mm ON sys_category_record_mm.uid_local = sys_category.uid + orderBy = sorting + as = compatibleWith + } + } + } + + 100 < .10 + 100 { + if.value = 100 + special > + special = categories + special.value { + data = GP:tag_id + intval = 1 + } + } + + 500 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor + 500 { + if { + value = 100 + equals.field = layout + } + table = sys_category + pidInList = 2 + where = uid = ###UID### + markers { + UID { + data = GP:tag_id + intval = 1 + } + } + as = tagForFilter } } } diff --git a/Configuration/TypoScript/Setup/Page.typoscript b/Configuration/TypoScript/Setup/Page.typoscript index 79a65c2..b0c298f 100644 --- a/Configuration/TypoScript/Setup/Page.typoscript +++ b/Configuration/TypoScript/Setup/Page.typoscript @@ -36,17 +36,19 @@ page { 10 { table = sys_category pidInList = 2 - where = sys_category_record_mm.uid_foreign = {page:uid} AND sys_category.parent = 1 + where = sys_category_record_mm.uid_foreign = {page:uid} AND sys_category.parent = 1 where.insertData = 1 - join = sys_category_record_mm ON sys_category_record_mm.uid_local = sys_category.uid - orderBy = sorting - as = tags + leftjoin = sys_category_record_mm ON sys_category_record_mm.uid_local = sys_category.uid + orderBy = count DESC, sys_category.title ASC + as = assignedTags } 11 < .10 11 { - where = sys_category_record_mm.uid_foreign = {page:uid} AND sys_category.parent = 2 - as = compatible + where = sys_category_record_mm.uid_foreign = {page:uid} AND sys_category.parent = 2 + orderBy = sorting + as = compatibleWith } + 50 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor 50 { special = list @@ -63,6 +65,20 @@ page { } as = pageSections } + + 100 < .10 + 100 { + selectFields = sys_category.*, count(sys_category_record_mm.uid_foreign) as count + where = sys_category.parent = 1 AND sys_category_record_mm.uid_foreign IS NOT NULL + groupBy = sys_category.uid + as = allTags + } + 101 < .100 + 101 { + where = sys_category.parent = 2 AND sys_category_record_mm.uid_foreign IS NOT NULL + orderBy = sorting + as = allTypo3Compatible + } } settings { @@ -77,12 +93,18 @@ page { } } contentMain =< styles.content.get - footer =< styles.content.get - footer { + acknowledgements =< styles.content.get + acknowledgements { select { where = {#colPos}=100 } } + furtherReading =< styles.content.get + furtherReading { + select { + where = {#colPos}=200 + } + } } } } diff --git a/Resources/Private/Layouts/ContentElements/Default.html b/Resources/Private/Layouts/ContentElements/Default.html index acbfcbd..4ec9550 100644 --- a/Resources/Private/Layouts/ContentElements/Default.html +++ b/Resources/Private/Layouts/ContentElements/Default.html @@ -2,11 +2,11 @@ data-namespace-typo3-fluid="true"> - - - -

{data.header}

-
+ {f:render(partial: 'Header', arguments: { + uid: data.uid, + layout: data.header_layout, + header: data.header + })}
{f:render(section: 'Content', arguments: _all)} diff --git a/Resources/Private/Partials/BlogPostHeader.html b/Resources/Private/Partials/BlogPostHeader.html new file mode 100644 index 0000000..b7f6277 --- /dev/null +++ b/Resources/Private/Partials/BlogPostHeader.html @@ -0,0 +1,20 @@ + + +
+

{f:if( + condition: link, + then: '{title}', + else: title + )}

+

+ Published: , + Updated: +

+

Tested with TYPO3: + + {version.data.title}{f:if(condition: '!{i.isLast}', then: ',')} + +

+
+ diff --git a/Resources/Private/Partials/ContentElements/Header.html b/Resources/Private/Partials/ContentElements/Header.html new file mode 100644 index 0000000..9c31aa4 --- /dev/null +++ b/Resources/Private/Partials/ContentElements/Header.html @@ -0,0 +1,8 @@ + + + + +

{header}

+
+ diff --git a/Resources/Private/Partials/Menu/Page.html b/Resources/Private/Partials/Menu/Page.html index f5baf33..5f82430 100644 --- a/Resources/Private/Partials/Menu/Page.html +++ b/Resources/Private/Partials/Menu/Page.html @@ -1,11 +1,11 @@
-
-

{page.title}

-

- -

-
+ {f:render(partial: 'BlogPostHeader', arguments: { + link: page.link, + title: page.title, + blogPost : page.data, + compatibleWith: page.compatibleWith + })} {page.data.abstract -> f:format.html()} diff --git a/Resources/Private/Partials/TagList.html b/Resources/Private/Partials/TagList.html new file mode 100644 index 0000000..71ed487 --- /dev/null +++ b/Resources/Private/Partials/TagList.html @@ -0,0 +1,16 @@ + + + diff --git a/Resources/Private/Sass/layout/pages/_singleBlogPost.scss b/Resources/Private/Sass/layout/pages/_singleBlogPost.scss index 4d86356..eace8c1 100644 --- a/Resources/Private/Sass/layout/pages/_singleBlogPost.scss +++ b/Resources/Private/Sass/layout/pages/_singleBlogPost.scss @@ -1,5 +1,10 @@ article.single-blog-post { padding-top: 0; + + > header { + margin-bottom: 0; + } + h1, h2, h3, h4, h5, h6 { padding-top: $spacer * 2; } diff --git a/Resources/Private/Templates/ContentElements/MenuAbstract.html b/Resources/Private/Templates/ContentElements/MenuAbstract.html index 4714226..54a600e 100644 --- a/Resources/Private/Templates/ContentElements/MenuAbstract.html +++ b/Resources/Private/Templates/ContentElements/MenuAbstract.html @@ -3,14 +3,17 @@ {f:layout(name: 'Default')} + + {f:render(partial: 'Header', arguments: { + uid: data.uid, + layout: data.header_layout, + header: '{data.header} {tagForFilter.0.data.title}' + })} + + {f:render(partial: 'Menu/Page', arguments: {page: page})} - - - - - diff --git a/Resources/Private/Templates/Page/BlogPost.html b/Resources/Private/Templates/Page/BlogPost.html index 55d8095..b4482d8 100644 --- a/Resources/Private/Templates/Page/BlogPost.html +++ b/Resources/Private/Templates/Page/BlogPost.html @@ -8,18 +8,11 @@

Blog Post

-
-

{data.title}

-

- Published: , - Updated: -

-

Tested with TYPO3: - - {version.data.title}{f:if(condition: '!{i.isLast}', then: ',')} - -

-
+ {f:render(partial: 'BlogPostHeader', arguments: { + title: data.title, + blogPost : data, + compatibleWith: compatibleWith + })}

Introduction

@@ -28,26 +21,27 @@ {contentMain -> f:format.raw()} - {footer -> f:format.raw()} + + +

Acknowledgements

+ {acknowledgements -> f:format.raw()} +
+ + + +

Further reading

+ {furtherReading -> f:format.raw()} +
{f:render(section: 'TOC', arguments: _all)} - - - - - - + {f:render(partial: 'TagList', arguments: { + headline: 'Related Tags', + tags: assignedTags + })} @@ -65,6 +59,16 @@ + +
  • + Acknowledgements +
  • +
    + +
  • + Further reading +
  • +
    diff --git a/Resources/Private/Templates/Page/Default.html b/Resources/Private/Templates/Page/Default.html index 163063a..984b363 100644 --- a/Resources/Private/Templates/Page/Default.html +++ b/Resources/Private/Templates/Page/Default.html @@ -12,36 +12,14 @@ -
    -

    About

    -

    Etiam porta sem malesuada magna mollis euismod. Cras mattis consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla sed consectetur.

    -
    + {f:render(partial: 'TagList', arguments: { + headline: 'Compatible with TYPO3', + tags: allTypo3Compatible + })} - - -
    -

    Elsewhere

    -
      -
    1. GitHub
    2. -
    3. Twitter
    4. -
    5. Facebook
    6. -
    -
    + {f:render(partial: 'TagList', arguments: { + headline: 'Tags', + tags: allTags + })}
    diff --git a/Resources/Public/Css/index.css b/Resources/Public/Css/index.css index 2a9828a..d35c126 100644 --- a/Resources/Public/Css/index.css +++ b/Resources/Public/Css/index.css @@ -1 +1 @@ -*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:monospace;font-size:1.25rem;font-weight:400;line-height:1.5;color:#d3d7cf;text-align:left;background-color:#2e3436}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}dl,h1,h2,h3,h4,h5,h6,ol,p,ul{margin-top:0;margin-bottom:.5rem}dl,ol,p,ul{margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote,figure{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a,a:hover{text-decoration:underline}a{background-color:transparent;color:#72b3cc}a:hover{color:#9cd9f0}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}img,svg{vertical-align:middle}img{border-style:none}svg{overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}h1 small a,h2 small a,h3 small a,h4 small a,h5 small a,h6 small a,template{display:none}[hidden]{display:none!important}.container,body{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,body{max-width:40rem}}@media (min-width:768px){.container,body{max-width:50rem}}@media (min-width:992px){.container,body{max-width:70rem}}@media (min-width:1200px){.container,body{max-width:100rem}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row,body>header,body>main{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,body>header .website-title,body>header nav{position:relative;width:100%;padding-right:15px;padding-left:15px}.col-auto{position:relative;padding-right:15px;padding-left:15px}.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto,body>main>aside,body>main>section{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{flex-basis:0;flex-grow:1;max-width:100%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.33333%;max-width:8.33333%}.col-2{flex:0 0 16.66667%;max-width:16.66667%}.col-3{flex:0 0 25%;max-width:25%}.col-4,body>header nav{flex:0 0 33.33333%;max-width:33.33333%}.col-5{flex:0 0 41.66667%;max-width:41.66667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.33333%;max-width:58.33333%}.col-8,body>header .website-title{flex:0 0 66.66667%;max-width:66.66667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.33333%;max-width:83.33333%}.col-11{flex:0 0 91.66667%;max-width:91.66667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}@media (min-width:576px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.33333%;max-width:8.33333%}.col-sm-2{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.33333%;max-width:33.33333%}.col-sm-5{flex:0 0 41.66667%;max-width:41.66667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.33333%;max-width:58.33333%}.col-sm-8{flex:0 0 66.66667%;max-width:66.66667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.33333%;max-width:83.33333%}.col-sm-11{flex:0 0 91.66667%;max-width:91.66667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}}@media (min-width:768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.33333%;max-width:8.33333%}.col-md-2{flex:0 0 16.66667%;max-width:16.66667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4,body>main>aside{flex:0 0 33.33333%;max-width:33.33333%}.col-md-5{flex:0 0 41.66667%;max-width:41.66667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.33333%;max-width:58.33333%}.col-md-8,body>main>section{flex:0 0 66.66667%;max-width:66.66667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.33333%;max-width:83.33333%}.col-md-11{flex:0 0 91.66667%;max-width:91.66667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}}@media (min-width:992px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.33333%;max-width:8.33333%}.col-lg-2{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.33333%;max-width:33.33333%}.col-lg-5{flex:0 0 41.66667%;max-width:41.66667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}.col-lg-8{flex:0 0 66.66667%;max-width:66.66667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.33333%;max-width:83.33333%}.col-lg-11{flex:0 0 91.66667%;max-width:91.66667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}}@media (min-width:1200px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.33333%;max-width:8.33333%}.col-xl-2{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.33333%;max-width:33.33333%}.col-xl-5{flex:0 0 41.66667%;max-width:41.66667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.33333%;max-width:58.33333%}.col-xl-8{flex:0 0 66.66667%;max-width:66.66667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.33333%;max-width:83.33333%}.col-xl-11{flex:0 0 91.66667%;max-width:91.66667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}}:root{--blue: #9CD9F0;--indigo: #6610f2;--purple: #6f42c1;--pink: #FBB1F9;--red: #E09690;--orange: #fd7e14;--yellow: #FFE377;--green: #CDEE69;--teal: #20c997;--cyan: #77DFD8;--white: #F7F7F7;--gray: #6c757d;--gray-dark: #343a40;--primary: #9CD9F0;--secondary: #72B3CC;--success: #CDEE69;--info: #9CD9F0;--warning: #FFE377;--danger: #E09690;--light: #B0B0B0;--dark: #5D5D5D;--breakpoint-xs: 0;--breakpoint-sm: 576px;--breakpoint-md: 768px;--breakpoint-lg: 992px;--breakpoint-xl: 1200px;--font-family-sans-serif: "Helvetica", sans-serif;--font-family-monospace: monospace}body>header{padding-bottom:4rem}body>header .website-title a{font-size:3.125rem;text-decoration:none}body>header nav{text-align:right}body>header nav a{color:#6c757d!important}aside nav ul{list-style:none;padding-left:0}li{padding-bottom:.5rem;padding-top:.5rem}body>footer{padding-top:2rem;text-align:center}h1:hover small a,h2:hover small a,h3:hover small a,h4:hover small a,h5:hover small a,h6:hover small a{display:inline;color:#adb5bd}section>header{font-size:1.5em}article,section>header{padding-bottom:2rem}article>header{font-size:1.25em;margin-bottom:2rem}article>header h1,article>header h2,article>header h3,article>header h4,article>header h5,article>header h6{margin-bottom:0;padding-bottom:0}article>header p{font-size:.75em;margin:0}article.single-blog-post{padding-top:0}article,article.single-blog-post h1,article.single-blog-post h2,article.single-blog-post h3,article.single-blog-post h4,article.single-blog-post h5,article.single-blog-post h6{padding-top:2rem}code{background:#000;color:#b0b0b0;padding-left:.5em;padding-right:.5em;white-space:nowrap}pre code{display:block;overflow-x:auto;padding:.5em;white-space:pre}pre code .tag{color:#f7f7f7}pre code .attr,pre code .tag .name{color:#9cd9f0}pre code .string{color:#b0b0b0}pre code .function{color:#f7f7f7}pre code .keyword{color:#cdee69}pre code .params .string{color:#5d5d5d} \ No newline at end of file +*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:monospace;font-size:1.25rem;font-weight:400;line-height:1.5;color:#d3d7cf;text-align:left;background-color:#2e3436}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}dl,h1,h2,h3,h4,h5,h6,ol,p,ul{margin-top:0;margin-bottom:.5rem}dl,ol,p,ul{margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}article.single-blog-post>header,ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote,figure{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a,a:hover{text-decoration:underline}a{background-color:transparent;color:#72b3cc}a:hover{color:#9cd9f0}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}img,svg{vertical-align:middle}img{border-style:none}svg{overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}h1 small a,h2 small a,h3 small a,h4 small a,h5 small a,h6 small a,template{display:none}[hidden]{display:none!important}.container,body{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,body{max-width:40rem}}@media (min-width:768px){.container,body{max-width:50rem}}@media (min-width:992px){.container,body{max-width:70rem}}@media (min-width:1200px){.container,body{max-width:100rem}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row,body>header,body>main{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,body>header .website-title,body>header nav{position:relative;width:100%;padding-right:15px;padding-left:15px}.col-auto{position:relative;padding-right:15px;padding-left:15px}.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto,body>main>aside,body>main>section{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{flex-basis:0;flex-grow:1;max-width:100%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.33333%;max-width:8.33333%}.col-2{flex:0 0 16.66667%;max-width:16.66667%}.col-3{flex:0 0 25%;max-width:25%}.col-4,body>header nav{flex:0 0 33.33333%;max-width:33.33333%}.col-5{flex:0 0 41.66667%;max-width:41.66667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.33333%;max-width:58.33333%}.col-8,body>header .website-title{flex:0 0 66.66667%;max-width:66.66667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.33333%;max-width:83.33333%}.col-11{flex:0 0 91.66667%;max-width:91.66667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}@media (min-width:576px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.33333%;max-width:8.33333%}.col-sm-2{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.33333%;max-width:33.33333%}.col-sm-5{flex:0 0 41.66667%;max-width:41.66667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.33333%;max-width:58.33333%}.col-sm-8{flex:0 0 66.66667%;max-width:66.66667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.33333%;max-width:83.33333%}.col-sm-11{flex:0 0 91.66667%;max-width:91.66667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}}@media (min-width:768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.33333%;max-width:8.33333%}.col-md-2{flex:0 0 16.66667%;max-width:16.66667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4,body>main>aside{flex:0 0 33.33333%;max-width:33.33333%}.col-md-5{flex:0 0 41.66667%;max-width:41.66667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.33333%;max-width:58.33333%}.col-md-8,body>main>section{flex:0 0 66.66667%;max-width:66.66667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.33333%;max-width:83.33333%}.col-md-11{flex:0 0 91.66667%;max-width:91.66667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}}@media (min-width:992px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.33333%;max-width:8.33333%}.col-lg-2{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.33333%;max-width:33.33333%}.col-lg-5{flex:0 0 41.66667%;max-width:41.66667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}.col-lg-8{flex:0 0 66.66667%;max-width:66.66667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.33333%;max-width:83.33333%}.col-lg-11{flex:0 0 91.66667%;max-width:91.66667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}}@media (min-width:1200px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.33333%;max-width:8.33333%}.col-xl-2{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.33333%;max-width:33.33333%}.col-xl-5{flex:0 0 41.66667%;max-width:41.66667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.33333%;max-width:58.33333%}.col-xl-8{flex:0 0 66.66667%;max-width:66.66667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.33333%;max-width:83.33333%}.col-xl-11{flex:0 0 91.66667%;max-width:91.66667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}}:root{--blue: #9CD9F0;--indigo: #6610f2;--purple: #6f42c1;--pink: #FBB1F9;--red: #E09690;--orange: #fd7e14;--yellow: #FFE377;--green: #CDEE69;--teal: #20c997;--cyan: #77DFD8;--white: #F7F7F7;--gray: #6c757d;--gray-dark: #343a40;--primary: #9CD9F0;--secondary: #72B3CC;--success: #CDEE69;--info: #9CD9F0;--warning: #FFE377;--danger: #E09690;--light: #B0B0B0;--dark: #5D5D5D;--breakpoint-xs: 0;--breakpoint-sm: 576px;--breakpoint-md: 768px;--breakpoint-lg: 992px;--breakpoint-xl: 1200px;--font-family-sans-serif: "Helvetica", sans-serif;--font-family-monospace: monospace}body>header{padding-bottom:4rem}body>header .website-title a{font-size:3.125rem;text-decoration:none}body>header nav{text-align:right}body>header nav a{color:#6c757d!important}aside nav ul{list-style:none;padding-left:0}li{padding-bottom:.5rem;padding-top:.5rem}body>footer{padding-top:2rem;text-align:center}h1:hover small a,h2:hover small a,h3:hover small a,h4:hover small a,h5:hover small a,h6:hover small a{display:inline;color:#adb5bd}section>header{font-size:1.5em}article,section>header{padding-bottom:2rem}article>header{font-size:1.25em;margin-bottom:2rem}article>header h1,article>header h2,article>header h3,article>header h4,article>header h5,article>header h6{margin-bottom:0;padding-bottom:0}article>header p{font-size:.75em;margin:0}article.single-blog-post{padding-top:0}article,article.single-blog-post h1,article.single-blog-post h2,article.single-blog-post h3,article.single-blog-post h4,article.single-blog-post h5,article.single-blog-post h6{padding-top:2rem}code{background:#000;color:#b0b0b0;padding-left:.5em;padding-right:.5em;white-space:nowrap}pre code{display:block;overflow-x:auto;padding:.5em;white-space:pre}pre code .tag{color:#f7f7f7}pre code .attr,pre code .tag .name{color:#9cd9f0}pre code .string{color:#b0b0b0}pre code .function{color:#f7f7f7}pre code .keyword{color:#cdee69}pre code .params .string{color:#5d5d5d} \ No newline at end of file diff --git a/ext_tables.sql b/ext_tables.sql new file mode 100644 index 0000000..8401104 --- /dev/null +++ b/ext_tables.sql @@ -0,0 +1,3 @@ +CREATE TABLE sys_category ( + slug varchar(2048), +);