antville/code/Site/$Site.skin

1356 lines
38 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<% #href %>
<% param.path %>
<% #listItem %>
<tr>
<td class='uk-width-6-10'><% site.title | site.link %></td>
<td class='uk-text-truncate' title='<% site.modified short %>' data-uk-tooltip="{pos: 'top-left'}">
<% site.modified text %>
</td>
<td><% site.modifier %></td>
</tr>
<% #edit %>
<h1><% response.title %></h1>
<div class='uk-article-meta'>
<% if <% this.creator %> is null then '' else
<% gettext 'Created by {0} on {1}' <% this.creator %> <% this.created short %> %>
%>
<% if <% this.created %> is <% this.configured %> then '' else
<% gettext 'Last modified by {0} on {1}' <% this.modifier %> <% this.configured | format short date %> prefix=<br> %>
%>
</div>
<div class='uk-margin-top uk-margin-bottom'>
<% site.link export <% gettext Export %> %>
</div>
<form class='uk-form uk-form-stacked' id="edit" method="post" action="<% response.action %>">
<fieldset>
<div class='uk-form-row'>
<label class='uk-form-label' for='mode'>
<% gettext Mode %>
</label>
<div class='uk-form-controls'>
<% site.select mode %>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label' for='title'>
<% gettext Title %>
</label>
<div class='uk-form-controls'>
<% site.input title class='uk-width-1-1' %>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label' for='tagline'>
<% gettext Description %>
</label>
<div class='uk-form-controls'>
<% site.input tagline class='uk-width-1-1' %>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label' for='pageSize'>
<% gettext Pagination %>
</label>
<div class='uk-form-controls'>
<% site.input pageSize class='uk-width-1-6' type=number min=1 max=25 %>
<% gettext "{0} per page" <% gettext "stories" %> %>
<% // site.select pageMode %>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label' for='commentMode'>
<% gettext Comments %>
</label>
<div class='uk-form-controls'>
<label>
<% site.checkbox commentMode %>
<% gettext enabled %>
</label>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label' for='archiveMode'>
<% gettext Archive %>
</label>
<div class='uk-form-controls'>
<label>
<% site.checkbox archiveMode %>
<% gettext enabled %>
</label>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label' for='locale'>
<% gettext Language %>
</label>
<div class='uk-form-controls'>
<% site.select locale %>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label' for='timeZone'>
<% gettext 'Time Zone' %>
</label>
<div class='uk-form-controls'>
<% site.select timeZone %>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label' for='notificationMode'>
<% gettext Notifications %>
</label>
<div class='uk-form-controls'>
<% site.select notificationMode %>
</div>
</div>
</fieldset>
<fieldset class='uk-margin-top'>
<legend><% gettext Advanced %></legend>
<div class='uk-form-row'>
<label class='uk-form-label' for='maxImageWidth'>
<% gettext 'Image Dimension Limits' %>
<i class='uk-icon-info-circle uk-text-muted' title='<% gettext "If you want to resize the image please specify your desired maximum width and/or maximum height in pixels. If you specify both the image will be resized to match both criterias, but the image ratio will be preserved. If the width or height of your image exceeds 100 pixels Antville automatically creates a thumbnail of it, too." %> ' data-uk-tooltip='{pos: "right"}'></i>
</label>
<div class='uk-form-controls'>
<% site.input maxImageWidth type='number' min=1 class='uk-form-width-small' %>
&times;
<% site.input maxImageHeight type='number' min=1 class='uk-form-width-small' %> <% gettext Pixels %>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label' for='trollFilter'>
<% gettext 'Robot rules' %>
</label>
<div class='uk-form-controls'>
<label>
<% site.checkbox robotsTxtMode %>
<% gettext enforced %>
</label>
<p class="uk-form-help-block">
<% gettext 'Edit the rules in the <a href="{0}Site/robots/edit">robots.txt</a> skin.' <% site.layout.skins.href %> %>
</p>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label' for='trollFilter'>
<% gettext 'Troll Filter' %>
</label>
<div class='uk-form-controls'>
<% site.textarea trollFilter rows=5 class='uk-width-1-1' %>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label' for='spamfilter' >
<% gettext 'Referrer Filter' %>
</label>
<div class='uk-form-controls'>
<% site.textarea spamfilter rows=5 class='uk-width-1-1' %>
<p class="uk-form-help-block">
<% gettext "Enter one filter {0}pattern{1} per line to be applied on every URL in the referrer and backlink lists." '<a href="http://en.wikipedia.org/wiki/Regular_expression">' </a> %>
</p>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label' for='callbackUrl'>
<% gettext 'Callback URL' %>
</label>
<div class='uk-form-controls' x-data='{ callbackMode: false }'>
<% site.input callbackUrl type=url class='uk-width-1-1' :disabled='!callbackMode' %>
<label>
<% site.checkbox callbackMode x-model='callbackMode' %>
<% gettext enabled %>
</label>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label'>
<% gettext Bookmarklet %>
</label>
<div class='uk-form-controls'>
<a class='uk-button' data-uk-tooltip='{ pos: "right" }' href="javascript: void (() => { const F = { '🍪': '', '🐜': '<% root.static %>../../formica.html', '🎯': '<% site.href %>', '🌐': '<% root.href %>', '📝': window.getSelection ? window.getSelection() : document.selection.createRange() }; F['📝'] = '' + (F['📝'].text || F['📝']); F['🐜'] += '?s=' + encodeURIComponent(F['🎯']) + '&amp;l=' + encodeURIComponent(location.href) + '&amp;r=' + encodeURIComponent(document.referrer) + '&amp;k=' + encodeURIComponent(F['🍪']) + '&c=' + encodeURIComponent(F['📝']) + '&b=' + encodeURIComponent(F['🌐']); window.open(F['🐜'], '🐜', 'width=650, height=350'); })()" title="<% gettext 'Drag to Bookmarks Bar' %>"><% gettext "Post to {0}" <% site.title %> %></a>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label'>
<% gettext 'Disk Space' %>
</label>
<div class='uk-form-controls'>
<% site.diskspace %>
</div>
</div>
</fieldset>
<% site.skin $Site#admin restricted=true %>
<div class='uk-margin-top'>
<button class='uk-button uk-button-primary' type="submit" id="submit" name="save" value="1">
<% gettext Save %>
</button>
<% site.link delete <% gettext Delete %> class='uk-button' %>
<a href='<% site.href %>' class="uk-button uk-button-link"><% gettext Cancel %></a>
</div>
</form>
<script>
document.addEventListener("alpine:init", () => {
// Group related <option> elements by inserting additional <optgroup> elements.
const dom = window;
const groups = [];
dom.timeZone.querySelectorAll('option').forEach(function(item, index) {
const parts = item.innerHTML.split('/'); // E.g. Europe/Vienna
const group = parts[0];
if (groups.indexOf(group) < 0) {
groups.push(group);
}
});
groups.sort();
groups.forEach(function(group, index) {
const key = group + '/'; // E.g. Europe/
const optgroup = document.createElement('optgroup');
optgroup.setAttribute('label', group);
dom.timeZone.querySelectorAll('option[value^="' + key + '"]').forEach(function(option) {
option.innerHTML = option.innerHTML.replace(key, '');
optgroup.appendChild(option);
});
dom.timeZone.appendChild(optgroup);
// Correct the selected index
timeZone.selectedIndex = Array.from(timeZone.options).indexOf(timeZone.querySelector('option[selected]'));
});
});
</script>
<% #meta %>
<meta name='description' content='<% response.description %>'>
<meta name='twitter:card' content='summary_large_image'>
<meta name='twitter:title' property='og:title' itemprop='name' content='<% response.title %>'>
<meta name='twitter:description' property='og:description' itemprop='description' content='<% response.description default=<% response.title %> %>'>
<meta property='og:type' content='<% response.type %>'>
<meta property='og:site_name' content='<% site.title %>'>
<meta property='og:url' content='<% href %>'>
<% // Facebook is very picky with locales (e.g. complains about 'de' and 'en_AU') %>
<% //site.locale prefix="<meta property='og:locale' content='" suffix="'>" %>
<% response.images %>
<% response.videos %>
<% #links %>
<link rel='alternate' type='application/rss+xml' title='Stories and comments of <% site.title %>' href='<% site.href rss.xml %>'>
<link rel='alternate' type='application/rss+xml' title='Stories of <% site.title %>' href='<% site.href stories.xml %>'>
<link rel='alternate' type='application/rss+xml' title='Comments of <% site.title %>' href='<% site.href comments.xml %>'>
<link rel='alternate' type='application/rss+xml' title='Sites of <% root.title %>' href='<% root.href updates.xml %>'>
<link rel='search' type='application/opensearchdescription+xml' href='<% site.href search.xml %>' title='<% site.title %>'>
<% #menuButton %>
<input type='checkbox' class='av-menu-toggle'>
<i class='av-menu-toggle'></i>
<% #admin %>
<a name='admin' id='admin'></a>
<fieldset class='uk-margin-top'>
<legend><% gettext Administration %></legend>
<div class='uk-form-row'>
<label class='uk-form-label' for='status'>
<% gettext Status %>
</label>
<div class='uk-form-controls'>
<% site.select status %>
</div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label' for='status'>
<% gettext Information %>
</label>
<div><% ngettext "{0} Story" "{0} Stories" <% count <% site.self stories %> %> %></div>
<div><% ngettext "{0} Comment" "{0} Comments" <% count <% site.self comments %> %> %></div>
<div><% ngettext "{0} Image" "{0} Images" <% count <% site.self images %> %> %></div>
<div><% ngettext "{0} File" "{0} Files" <% count <% site.self files %> %> %></div>
</div>
<div class='uk-form-row'>
<label class='uk-form-label' for='notes'>
<% gettext Notes %>
</label>
<div class='uk-form-controls'>
<% site.textarea notes class='uk-width-1-1' rows=5 %>
</div>
</div>
</fieldset>
<% #delete %>
<div class='uk-alert uk-alert-danger'>
<% gettext 'You are about to delete the whole site which currently contains {0}, {1}, {2}, {3} and {4}.'
<% ngettext '{0} story' '{0} stories' <% count <% site.self stories %> %> %>
<% ngettext '{0} comment' '{0} comments' <% count <% site.self comments %> %> %>
<% ngettext '{0} image' '{0} images' <% count <% site.self images %> %> %>
<% ngettext '{0} file' '{0} files' <% count <% site.self files %> %> %>
<% ngettext '{0} poll' '{0} polls' <% count <% site.self polls %> %> %> %>
<strong><% gettext 'All of this will be deleted irreversibly.' %></strong>
<% gettext 'Are you sure you want to proceed?' %>
</div>
<% #search %>
<h1><% response.title %></h1>
<form class='uk-form' method='post' action='<% site.href search %>'>
<div class='uk-form-controls'>
<input type='text' class='uk-width-1-2' name='q' value='<% request.q encoding="form" %>' required>
<button type='submit' name='search' value='1' class='uk-button uk-button-primary'>
<% gettext Find %>
</button>
<a href='<% site.href %>' class='uk-button uk-button-link'><% gettext Cancel %></a>
</div>
</form>
<p>
<% if <% response.count %> is null then '' else <% ngettext 'Showing {0} result' 'Showing {0} results' <% response.count %> suffix=. %> %>
</p>
<dl class='uk-description-list-line'>
<% response.result %>
</dl>
<% if <% property search.provider %> is null then '' else <% site.skin $Site#moreResults %> %>
<% #moreResults %>
<a href='<% property search.provider %>?q=<% request.q encoding="url" %>+site:<% site.href %>' class='uk-button uk-align-right'>
<% gettext 'Search with {0}' <% property search.provider | replace 'https?://([^/]+).*' '$1' %> %>
<i class='uk-icon uk-icon-arrow-circle-right'></i>
</a>
<% #opensearchdescription %>
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName><% site.title %></ShortName>
<Description>Search the site <% site.href %></Description>
<Tags>antville search</Tags>
<Image height="16" width="16" type="image/vnd.microsoft.icon"><% image /favicon.png url %></Image>
<Url type="text/html" template="<% site.href search %>?q={searchTerms}" />
<Query role="example" searchTerms="cat" />
</OpenSearchDescription>
<% #header %>
<header class='av-header <% if <% site.id %> is <% root.id %> then 'av-root-site' %>'>
<div class='av-header-bg-chaos'></div>
<div class='av-header-bg-dots'></div>
<div class='av-title'>
<% if <% site.id %> is <% root.id %> then
<% image /big.gif | site.link title=<% site.tagline %> %>
else
<% site.title | site.link title=<% site.tagline %> %>
%>
</div>
</header>
<% #footer %>
<footer>
<hr class='uk-margin-large-top'>
<div class='uk-text-small uk-margin-bottom uk-float-left'>
<div><% if <% site.created %> then <% gettext 'Created {0}' <% site.created text %> %> suffix=. %></div>
<div><% if <% site.modified %> then <% gettext 'Last modified {0}' <% site.modified text %> %> suffix=. %></div>
</div>
<div class='uk-text-right'>
<% image /smallchaos.gif | link https://project.antville.org %> &
<% image /helma.png | link https://github.com/antville/helma %>
</div>
</footer>
<% #javascript %>
// Injecting main.css if necessary for compatibility reasons
if (!document.querySelector('link[href="<% site.href main.css %>"]')) {
const link = document.createElement('link');
link.href = '<% site.href main.css %>';
link.rel = 'stylesheet';
document.head.appendChild(link);
}
<% site.skin Site#javascript | script %>
<% #include %>
// The void operator is necessary or we get some wicked error from browserify(?)
void (function(url) {
const script = document.createElement('script');
script.src = url;
document.head.appendChild(script);
})('<% param.href %>');
<% #stylesheet %>
@import '<% root.static ../../styles/main.min.css %>';
// FIXME: compatibility
@base-font: <% value 'base font' default='Helvetica Neue, Liberation Sans, Helvetica, Arial, sans-serif' %>;
@base-font-size: <% value 'base font size' default="14px e('/') 20px" %>;
@base-font-color: <% value 'base font color' default=#444 %>;
@big-font: <% value 'big font' default=@base-font %>;
@big-font-size: <% value 'big font size' default=inherit %>;
@big-font-color: <% value 'big font color' default=@base-font-color %>;
@small-font: <% value 'small font' default=@base-font %>;
@small-font-size: <% value 'small font size' default=inherit %>;
@small-font-color: <% value 'small font color' default=#999 %>;
@active-link-color: <% value 'active link color' default=#d50000 %>;
//
@background: <% value 'background color' default=#fff %>;
@text-color: <% value 'text color' default=@base-font-color %>;
@title-color: <% value 'title color' default=@big-font-color %>;
@link-color: <% value 'link color' default=#ff4040 %>;
@hover-color: <% value 'hover color' default=@active-link-color %>;
@muted-color: <% value 'muted color' default=@small-font-color %>;
@muted-background: fadeout(@muted-color, 90%);
@border-color: fadeout(@muted-color, 75%);
@text-font: normal @base-font-size <% value 'text font' default=@base-font %>;
@title-font: <% value 'title font' default=@big-font %>;
// Overwriting some classes defined by UIKit to go along with Antvilles layout
html, html.uk-notouch, body {
background-color: @background;
color: @text-color;
font: @text-font;
}
body.av-16, body.av-page {
max-width: 900px;
margin: 1em 5%;
}
h1, h2, h3, h4, h5, h6 {
color: @title-color;
font-family: @title-font;
}
a {
color: @link-color;
&:hover {
color: @hover-color;
}
&[href='javascript:'] {
display: none;
}
}
em {
color: @text-color;
small & {
color: @muted-color;
}
}
img {
body:not(.av-16) &, table & {
max-width: initial; // FIXME: compatibility
}
&[src$='pixel.gif'] {
width: initial;
height: initial;
}
}
hr {
border-top-color: @border-color;
}
.uk-description-list-line {
overflow: hidden;
}
.uk-text-muted, .uk-article-meta, .uk-description-list-line > dd {
color: @muted-color !important;
}
.uk-table-striped tbody tr:nth-of-type(odd) {
background: darken(@background, 2%);
}
.uk-table-striped tbody tr:hover {
background: fadeout(@link-color, 88%);
}
.uk-button-group.av-link-group a {
border-right: initial;
}
.uk-nav-divider + .uk-nav-divider,
.uk-nav-header + .uk-nav-header {
display: none;
}
.uk-nav-side .uk-nav-divider {
margin-top: 15px;
border-top: none;
}
.uk-nav-side > li > a {
color: @text-color;
&:hover {
background: @muted-background;
color: @text-color;
text-shadow: none;
}
}
.uk-alert {
background: @muted-background;
border-color: @muted-color;
color: @muted-color;
text-shadow: none;
}
.uk-icon-button {
&:link, &:visited {
background-color: @background;
color: @link-color;
border-color: @link-color;
text-shadow: initial;
}
&:hover {
background-color: @background;
color: @hover-color;
border-color: @hover-color;
text-shadow: initial;
}
}
.uk-button:not(.uk-button-success):not([disabled]) {
text-shadow: initial !important;
&, &:link, &:visited {
background-color: @background;
color: @text-color;
border-color: @text-color;
}
&:hover {
background-color: @background;
color: @hover-color;
border-color: @hover-color;
}
&.uk-button-link {
border-color: transparent;
&:link, &:visited {
color: @link-color;
}
&:hover {
color: @hover-color;
}
}
&.uk-button-primary {
background-color: @background;
border-style: double;
border-color: @link-color;
color: @link-color;
font-weight: bold;
&:hover {
background: inherit;
border-color: @hover-color;
color: @hover-color;
}
}
}
&.uk-button-primary[disabled] {
font-weight: bold;
}
.uk-pagination {
& > li > a {
background: @background;
color: @link-color;
border-color: @link-color;
text-shadow: initial;
&:hover {
background: @background;
color: @hover-color;
border-color: @hover-color;
}
}
& > .uk-active > span {
background: @background;
border-color: @text-color;
color: @text-color;
font-weight: bold;
}
& > .uk-disabled > span {
background: @muted-background;
color: @muted-color;
border-color: @muted-color;
text-shadow: initial;
}
}
.uk-subnav > li > a {
&:link, &:visited {
color: @link-color;
}
&:hover {
color: @hover-color;
}
}
.uk-nav-side > li.uk-active > a {
background: none;
color: @link-color;
box-shadow: none;
font-weight: bold;
}
.uk-thumbnail img {
body:not(.av-16) & {
max-width: 100%;
}
}
h1 a, .uk-table a {
&:visited {
color: @link-color;
}
&:hover {
color: @hover-color;
}
}
.uk-table th, .uk-table td, {
border-color: @border-color;
}
.uk-form legend:after {
content: '';
display: block;
border-bottom: 1px solid @border-color;
width: 100%;
}
.uk-form select,
.uk-form textarea,
.uk-form input:not([type]),
.uk-form input[type="text"],
.uk-form input[type="password"],
.uk-form input[type="datetime"],
.uk-form input[type="datetime-local"],
.uk-form input[type="date"],
.uk-form input[type="month"],
.uk-form input[type="time"],
.uk-form input[type="week"],
.uk-form input[type="number"],
.uk-form input[type="email"],
.uk-form input[type="url"],
.uk-form input[type="search"],
.uk-form input[type="tel"],
.uk-form input[type="color"] {
border-color: @border-color;
}
// Remove the left padding of the first meta subnav item for vertical alignment with the username
h4 + .uk-comment-meta li:first-child {
padding-left: 0;
}
.av-page {
overflow: auto;
}
.av-sprite {
display: inline-block;
vertical-align: middle;
}
.av-ant {
display: inline-block;
margin: 0 0 -2px -2px;
width: 15px;
height: 15px;
background-image: url(/static/img/ant.svg);
background-size: 15px 15px;
background-repeat: no-repeat;
}
.av-border-left {
border-left: 1px solid @border-color;
}
.av-overflow {
// FIXME: Is this cross-browser compatible?
max-width: 0;
overflow: hidden;
}
.av-invisible {
visibility: hidden;
}
.av-concealed-link {
color: inherit;
&:hover {
color: inherit;
}
}
.av-upload {
position: relative;
input[type='file'] {
position: relative;
z-index: 1;
visibility: hidden;
}
.av-upload-controls {
position: absolute;
z-index: 2;
top: 0;
left: 0;
}
}
.av-upload-drop {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.8);
z-index: 10;
i {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 20em;
&.av-upload-glow {
animation-name: av-upload-glow;
animation-duration: 3s;
animation-direction: alternate;
animation-iteration-count: infinte;
-webkit-animation-name: av-upload-glow;
-webkit-animation-duration: 0.5s;
-webkit-animation-direction: alternate;
-webkit-animation-iteration-count: infinite;
}
@keyframes av-upload-glow {
0% {color: inherit;}
100% {color: @link-color;}
}
@-webkit-keyframes av-upload-glow {
0% {color: inherit;}
100% {color: @link-color;}
}
}
}
.av-image-box {
display: inline-block;
max-width: 100%;
}
.av-collage {
padding: 0;
.av-tagged-image {
opacity: 0;
img {
max-width: 100%;
display: inline-block;
margin: 0;
padding: 0;
vertical-align: bottom;
opacity: 1;
}
.Caption_Content {
color: #fff;
padding: 10px;
}
}
}
.av-poll-result-bar {
display: inline-block;
height: 0.5rem;
overflow: hidden;
margin-right: 0.5rem;
background-color: @link-color;
}
.av-header {
position: relative;
height: 73px;
margin-top: 5px;
.av-header-bg-chaos {
width: 274px;
height: 53px;
margin-left: -53px;
background: url('<% image /spritesheet.png url %>');
background-position: -10px -139px;
background-repeat: no-repeat;
}
.av-header-bg-dots {
position: relative;
top: -46px;
margin-left: 222px;
margin-right: -5.6%;
height: 38px;
background: url('<% image /dot.gif url %>');
}
.av-title {
position: absolute;
top: 8px;
width: 100%;
height: 100%;
overflow-x: hidden;
white-space: nowrap;
line-height: 31px;
font-family: Verdana, Helvetica, Arial, sans-serif;
font-size: 25px;
font-weight: bold;
img {
max-width: initial;
}
}
// The root site gets the beautiful logo with ant animation
&.av-root-site {
.av-title {
top: 0px;
left: -55px;
}
}
}
.av-menu {
& .av-menu-toggle {
display: none;
}
}
@media (max-width: 767px) {
.av-menu {
@top: 23px;
@right: 5%;
@size: 30px;
i.av-menu-toggle {
.av-ant;
padding: 2px;
border-radius: 100%;
background-color: fadeout(@background, 20%);
background-size: @size @size;
background-position: 2px 2px;
}
i.av-menu-toggle,
input.av-menu-toggle {
display: initial;
position: absolute;
top: @top;
right: @right;
width: @size;
height: @size;
margin-right: 2px;
}
input.av-menu-toggle {
z-index: 9;
opacity: 0;
&:checked {
position: fixed;
width: 100%;
height: 100%;
& ~ .av-navigation {
display: initial;
}
}
}
.av-navigation {
display: none;
position: fixed;
top: 0;
right: 0;
bottom: 0;
z-index: 10;
padding: 10pt 10pt 10pt 0;
background-color: fadeout(@background, 10%);
box-shadow: -5px 0 5px 0 @border-color;
overflow: auto;
}
}
}
.av-skin-active {
background: #fff;
opacity: .25;
}
.av-locale-needs-translation {
color: @muted-color;
}
.av-layout-sandbox {
height: 22px;
}
.av-layout-sandbox div {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 22px;
padding: 0 20px;
background: url('<% image /sandbox.png url %>');
background-position: 0 23px;
text-align: left;
}
.av-skin-control {
margin: 5px 0;
}
.av-skin-edit-link {
padding: 2px;
text-decoration: none !important;
}
.av-rtl {
unicode-bidi: bidi-override;
direction: rtl;
}
// Overwriting some Helma and Jala classes for debugging and calendar integration
.helma-debug-line /*:has(script)*/ {
border: none !important;
}
.jala-calendar {
width: 100%;
max-width: 200px;
text-align: center;
tbody th {
font-weight: normal;
color: @text-color;
}
.jala-calendar-day {
width: 14.27%;
line-height: 1.2rem;
text-align: center;
a {
font-weight: bold;
}
}
.jala-calendar-selected {
border: 1px solid @muted-color;
border-radius: 4px;
font-weight: bold;
}
.jala-calendar-left {
text-align: center;
vertical-align: baseline;
}
.jala-calendar-right {
border: 0;
text-align: center;
vertical-align: baseline;
}
}
// AlpineJS https://alpinejs.dev/directives/cloak
[x-cloak] { display: none !important; }
// Overwriting some CSS classes for Googles custom search
.gs-webResult.gs-result a.gs-title:link,
.gs-webResult.gs-result a.gs-title:link b,
.gs-imageResult a.gs-title:link,
.gs-imageResult a.gs-title:link b {
color: @link-color !important;
}
.gs-webResult.gs-result a.gs-title:visited,
.gs-webResult.gs-result a.gs-title:visited b,
.gs-imageResult a.gs-title:visited,
.gs-imageResult a.gs-title:visited b {
color: @link-color !important;
}
.gs-result .gs-title, .gs-result .gs-title * {
text-decoration: none !important;
}
a.gs-title:hover {
text-decoration: underline !important;
}
.gsc-results {
border: none !important;
width: auto !important;
}
.cse .gsc-control-cse, .gsc-control-cse, .gsc-result-info, .gcsc-branding, .gsc-table-result, .gsc-thumbnail-inside, .gsc-url-top {
border: none !important;
padding-left: 0 !important;
padding-right: 0 !important;
}
.gsc-results .gsc-cursor-box {
margin: 10px 0 0 0 !important;
}
.gsc-result-info, .gsc-orderby-label, td.gsc-branding-text, td.gcsc-branding-text {
color: @muted-color !important;
}
.gs-no-results-result .gs-snippet, .gs-error-result .gs-snippet {
margin: 0 !important;
border: none !important;
padding: 0 !important;
background-color: inherit !important;
}
.gs-webResult div.gs-visibleUrl, .gs-imageResult div.gs-visibleUrl {
color: @muted-color !important;
}
.gsc-control-cse, .gsc-control-cse-en {
background: @background !important;
}
.gsc-webResult.gsc-result, .gsc-results .gsc-imageResult {
border: none !important;
background: none !important;
}
.gs-webResult .gs-snippet, .gs-imageResult .gs-snippet, .gs-fileFormatType {
color: @text-color !important;
}
.gsc-results .gsc-cursor-box .gsc-cursor-page {
color: @link-color !important;
background: none !important;
}
.gcsc-branding-img-noclear {
width: 51px;
height: 15px;
max-width: initial;
vertical-align: text-bottom;
}
.gsc-above-wrapper-area {
border-bottom-color: @border-color !important;
}
<% #referrers %>
<h1><% response.title %></h1>
<form class='uk-form' action="<% response.action %>" method="get">
<div class='uk-form-row'>
<input class='uk-width-1-2' type="text" name="filter" value="<% request.filter encoding="form" %>">
<button class='uk-button uk-button-primary' type="submit" name="submit" value="1"><% gettext Search %></button>
<a class='uk-button' href='<% site.href referrers %>'>
<% gettext Reset %>
</a>
<div class='uk-form-help-block'>
<label>
<input type="checkbox" id="includeSpam" name="includeSpam" value="checked" <% request.includeSpam prefix='checked="' suffix='"' encoding="form" %> />
<% gettext 'Disable filter' %>
<i class='uk-icon uk-icon-info-circle uk-text-muted' data-uk-tooltip="{pos: 'right'}" title='<% gettext "Edit the filter in the site settings." %>'></i>
</label>
</div>
</div>
<% site.skin $Site#referrerTable %>
</form>
<% #referrerTable %>
<% site.skin $Site#noscript %>
<table class='uk-table uk-table-condensed uk-table-striped uk-table-hover av-referrers'>
<thead>
<tr>
<th class='uk-text-right'><i class='uk-icon-bar-chart'></i></th>
<th><% gettext Referrer %></th>
<th></th>
</tr>
</thead>
<tbody>
<% response.list %>
</tbody>
</table>
<script>
document.addEventListener("alpine:init", () => {
const query = new Antville.Query();
const spamFilter = new Antville.Filter(JSON.parse('<% site.spamfilter %>'));
const searchFilter = new Antville.Filter(query.filter);
const searchEngineFilters = [
new Antville.Filter('//.*altavista.*/\\?', 'q'),
new Antville.Filter('//.*baidu.com/s\\?', 'wd'),
new Antville.Filter('//.*bing\\..*/search\\?', 'q'),
new Antville.Filter('//.*duckduckgo.com/\\?', 'q'),
new Antville.Filter('//.*google\\..*/imgres\\?', 'imgurl'),
new Antville.Filter('//.*google\\..*/\\?.*q=[^&]', 'q'),
new Antville.Filter('//.*haosou\\.com/s\\?', 'q'),
new Antville.Filter('//.*search\\.yahoo\\..*/\\?', 'p'),
new Antville.Filter('//.*search\\.ask\\.com/web\\?', '1'),
new Antville.Filter('//.*yandex\\..*/\\?', 'text')
];
const urlShortenerFilters = [
new Antville.Filter('//.*baidu.com/link'),
new Antville.Filter('//bit\\.ly/'),
new Antville.Filter('//.*duckduckgo.com/l/\\?'),
new Antville.Filter('//l.facebook.com/lrs.php'),
new Antville.Filter('//goo\\.gl/'),
new Antville.Filter('//.*google\\..*/url\\?'),
new Antville.Filter('//ift.tt'),
new Antville.Filter('//owl\\.ly/'),
new Antville.Filter('//t\\.co/'),
new Antville.Filter('//tinyurl\\.com/'),
new Antville.Filter('//.*stumbleupon\\.com/refer\\.php\\?'),
new Antville.Filter('//.*search\\.yahoo\\..*/.+/RU=')
];
let urlShortenerCounter = 0;
document.querySelectorAll('.av-referrer-row').forEach(function(row) {
const ref = row.querySelector('.av-referrer a');
const url = ref.getAttribute('href');
const count = row.querySelector('.av-referrer-count').innerText;
const control = row.querySelector('.av-referrer-control a');
const referrer = new Antville.Referrer(url, url, count);
ref.innerHTML = referrer.text;
control.addEventListener('click', function(event) {
event.preventDefault();
const input = prompt("<% gettext 'Are you sure you want to add this URL to the referrer filter? Edit it below to filter a pattern only.' %>", url);
if (!input) return;
location.href = '<% site.href referrers %>?submit=1&permanent=' + encodeURIComponent(input);
});
if (spamFilter.test(url)) {
if (query.includeSpam) {
ref.classList.add('uk-text-muted');
control.remove();
} else {
row.remove();
}
}
if (query.filter && !searchFilter.test(url)) {
row.remove();
}
const re = new RegExp('[:/].*$');
searchEngineFilters.forEach(function(filter) {
if (filter.test(url)) {
const host = referrer.text.replace(re, '');
ref.innerHTML = referrer.compose('<i><% gettext Search %>:</i>', filter.key);
}
});
urlShortenerFilters.forEach(function(filter) {
if (filter.test(url)) {
urlShortenerCounter += parseInt(count, 10);
const host = referrer.text.replace(re, '');
const url = referrer.url.replace(new RegExp('^(.+//[^/]+).*'), '$1');
ref.setAttribute('href', url);
ref.innerHTML = host;
}
});
});
document.querySelectorAll('.av-referrer a').forEach(function(element, index) {
const html = element.innerHTML;
const countElement = document.querySelectorAll('.av-referrer-count')[index];
let count = 0;
document.querySelectorAll('.av-referrer a').forEach(function(element2, index2) {
if (index2 <= index) return;
if (element2.innerHTML === html) {
count += parseInt(document.querySelectorAll('.av-referrer-count')[index2].innerText, 10);
element2.closest('.av-referrer-row').classList.add('av-delete');
}
});
if (count) countElement.innerHTML = parseInt(countElement.innerHTML, 10) + count;
});
document.querySelectorAll('.av-referrer-row.av-delete').forEach(function(element) {
element.remove();
});
const table = document.querySelector('.av-referrers tbody');
const rows = table.querySelectorAll('tr');
const sortedRows = Array.prototype.slice.call(rows).sort(function(a, b) {
return parseInt(b.querySelector('.av-referrer-count').innerText, 10) -
parseInt(a.querySelector('.av-referrer-count').innerText, 10);
});
sortedRows.forEach(function(row) { table.appendChild(row); });
});
</script>
<% #referrer %>
<tr class='av-referrer-row'>
<td class='uk-text-right av-referrer-count'><% param.requests %></td>
<td class='av-referrer av-overflow uk-width-1-1'>
<% param.referrer | link %>
</td>
<td class='av-referrer-control uk-text-right'>
<a href='javascript:'><i class='uk-icon uk-icon-filter'></i></a>
</td>
</tr>
<% #export %>
<h1><% gettext "Export Site Data" %></h1>
<p>
<% if <% param.status %> is null then <% if <% site.export %> is null then '' else <% gettext "{0}Download the archive{1} or click “Export” to create a new one." <% site.export prefix="<a href='" suffix="'>" %> "</a>" %> %> else <% param.status %> %>
</p>
<form action="<% site.href export %>" method="post">
<button type="submit" name="submit" value="<% if <% param.status %> is null then export else cancel %>" class='uk-button uk-button-primary'>
<% if <% param.status %> is null then <% gettext Export %> else <% gettext Cancel %> %>
</button>
<a href='<% site.href edit %>' class='uk-button uk-button-link'><% gettext Settings %></a>
</form>
<% #import %>
<h1><% gettext 'Import Site Data' %></h1>
<p>
<% if <% file.self %> is null then '' else <% gettext "The site is scheduled for importing the file {0}. The imported site data will be available within 24 hours." <% file.skin File#main %> '</a>' '<small>' <% file.created | format short %> '</small>' %> %>
</p>
<form class='uk-form uk-form-stacked' method="post" enctype="multipart/form-data">
<div class='uk-form-row'>
<label class='uk-form-label' for=''>
<% gettext File %>
</label>
<div class='uk-form-controls'>
<% if <% file.self %> is null then <% site.upload file %> %>
</div>
</div>
<div class='uk-form-row'>
<button class='uk-button uk-button-primary' type="submit" name="submit" value="<% if <% file.self %> is null then start else stop %>">
<% if <% file.self %> is null then <% gettext Start %> else <% gettext Stop %> %>
</button>
<a href='<% site.href %>' class='uk-button uk-button-link'><% gettext Cancel %></a>
</div>
</form>
<% #notify_block %>
<% gettext 'Hello {0}.' <% membership.name %> %>
<% gettext 'The site {0} at {1} will be blocked in {2} because it is being
restricted for too long.' <% site.title %> <%site.href %>
<% ngettext '{0} day' '{0} days' <% root.phaseOutGracePeriod %> %> %>
<% gettext "Best regards." %>
<% gettext "The Management" %>
<% #notify_delete %>
<% gettext 'Hello {0}.' <% membership.name %> %>
<% gettext 'The site {0} at {1} will be deleted in {2} because it has been
considered as abandoned.' <% site.title %> <% site.href %>
<% ngettext '{0} day' '{0} days' <% root.phaseOutGracePeriod %> %> %>
<% gettext "Best regards." %>
<% gettext "The Management" %>
<% #noscript %>
<noscript>
<div class='uk-margin-top'>
<i><% gettext 'Please enable JavaScript in your browser for improved functionality.' %></i>
</div>
</noscript>
<% #menuExt %>
<script defer='defer'>
const win = external.menuArguments;
const url = '<% site.url %>stories/create?text=';
const link = escape('<a href="' + win.location.href + '">' + win.document.title + '</a>: ');
const text = escape(win.document.selection.createRange().text);
win.location.href = url + link + text;
</script>
<% #menuExtRegistry %>
REGEDIT4
[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\Post to <% site.title %>]
@="<% site.url %>menuext"
"contexts"=hex:31