forked from GithubBackups/vichan
- board-search.php Now properly calculates tag weight.
- boards.php Passes $search parameters into Twig. - js/board-reictory.js Stores last search parameters and handles tag click events. - Twig now passes old search parameters into the search form. - Tags now link in such a way that they will preserve form data and other tags when clicked in a browser without JavaScript. Signed-off-by: 8n-tech <8n-tech@users.noreply.github.com>
This commit is contained in:
parent
67bab31510
commit
ec90c96459
@ -25,6 +25,7 @@ $languages = array(
|
|||||||
$search = array(
|
$search = array(
|
||||||
'lang' => false,
|
'lang' => false,
|
||||||
'nsfw' => true,
|
'nsfw' => true,
|
||||||
|
'page' => 0,
|
||||||
'tags' => false,
|
'tags' => false,
|
||||||
'time' => ( (int)( time() / 3600 ) * 3600 ) - 3600,
|
'time' => ( (int)( time() / 3600 ) * 3600 ) - 3600,
|
||||||
'title' => false,
|
'title' => false,
|
||||||
@ -37,6 +38,15 @@ if (isset( $_GET['sfw'] ) && $_GET['sfw'] != "") {
|
|||||||
$search['nsfw'] = !$_GET['sfw'];
|
$search['nsfw'] = !$_GET['sfw'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bringing up more results
|
||||||
|
if (isset( $_GET['page'] ) && $_GET['page'] != "") {
|
||||||
|
$search['page'] = (int) $_GET['page'];
|
||||||
|
|
||||||
|
if ($search['page'] < 0) {
|
||||||
|
$search['page'] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Include what language (if the language is not blank and we recognize it)?
|
// Include what language (if the language is not blank and we recognize it)?
|
||||||
if (isset( $_GET['lang'] ) && $_GET['lang'] != "" && isset($languages[$search['lang']])) {
|
if (isset( $_GET['lang'] ) && $_GET['lang'] != "" && isset($languages[$search['lang']])) {
|
||||||
$search['lang'] = $_GET['lang'];
|
$search['lang'] = $_GET['lang'];
|
||||||
@ -44,7 +54,8 @@ if (isset( $_GET['lang'] ) && $_GET['lang'] != "" && isset($languages[$search['l
|
|||||||
|
|
||||||
// Include what tag?
|
// Include what tag?
|
||||||
if (isset( $_GET['tags'] ) && $_GET['tags'] != "") {
|
if (isset( $_GET['tags'] ) && $_GET['tags'] != "") {
|
||||||
$search['tags'] = $_GET['tags'];
|
$search['tags'] = explode( " ", $_GET['tags'] );
|
||||||
|
$search['tags'] = array_splice( $search['tags'], 0, 5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// What time range?
|
// What time range?
|
||||||
@ -73,6 +84,31 @@ foreach ($boards as $board) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Are we searching by title?
|
||||||
|
if ($search['title'] !== false) {
|
||||||
|
// This checks each component of the board's identity against our search terms.
|
||||||
|
// The weight determines order.
|
||||||
|
// "left" would match /leftypol/ and /nkvd/ which has /leftypol/ in the title.
|
||||||
|
// /leftypol/ would always appear above it but it would match both.
|
||||||
|
if (strpos("/{$board['uri']}/", $search['title']) !== false) {
|
||||||
|
$board['weight'] = 30;
|
||||||
|
}
|
||||||
|
else if (strpos($board['title'], $search['title']) !== false) {
|
||||||
|
$board['weight'] = 20;
|
||||||
|
}
|
||||||
|
else if (strpos($board['subtitle'], $search['title']) !== false) {
|
||||||
|
$board['weight'] = 10;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset( $boardTitleString );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$board['weight'] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Load board config.
|
// Load board config.
|
||||||
$boardConfig = loadBoardConfig( $board['uri'] );
|
$boardConfig = loadBoardConfig( $board['uri'] );
|
||||||
|
|
||||||
@ -101,7 +137,7 @@ $boardTags = fetchBoardTags( array_keys( $response['boards'] ) );
|
|||||||
// Loop through each board and determine if there are tag matches.
|
// Loop through each board and determine if there are tag matches.
|
||||||
foreach ($response['boards'] as $boardUri => &$board) {
|
foreach ($response['boards'] as $boardUri => &$board) {
|
||||||
// If we are filtering by tag and there is no match, remove from the response.
|
// If we are filtering by tag and there is no match, remove from the response.
|
||||||
if ( $search['tags'] !== false && ( !isset( $boardTags[ $boardUri ] ) || !in_array( $search['tags'], $boardTags[ $boardUri ] )) ) {
|
if ( $search['tags'] !== false && ( !isset( $boardTags[ $boardUri ] ) || count(array_intersect($search['tags'], $boardTags[ $boardUri ])) !== count($search['tags']) ) ) {
|
||||||
unset( $response['boards'][$boardUri] );
|
unset( $response['boards'][$boardUri] );
|
||||||
}
|
}
|
||||||
// If we aren't filtering / there is a match AND we have tags, set the tags.
|
// If we aren't filtering / there is a match AND we have tags, set the tags.
|
||||||
@ -145,13 +181,16 @@ foreach ($response['boards'] as $boardUri => &$board) {
|
|||||||
// Sort boards by their popularity, then by their total posts.
|
// Sort boards by their popularity, then by their total posts.
|
||||||
$boardActivityValues = array();
|
$boardActivityValues = array();
|
||||||
$boardTotalPostsValues = array();
|
$boardTotalPostsValues = array();
|
||||||
|
$boardWeightValues = array();
|
||||||
|
|
||||||
foreach ($response['boards'] as $boardUri => &$board) {
|
foreach ($response['boards'] as $boardUri => &$board) {
|
||||||
$boardActivityValues[$boardUri] = (int) $board['active'];
|
$boardActivityValues[$boardUri] = (int) $board['active'];
|
||||||
$boardTotalPostsValues[$boardUri] = (int) $board['posts_total'];
|
$boardTotalPostsValues[$boardUri] = (int) $board['posts_total'];
|
||||||
|
$boardWeightValues[$boardUri] = (int) $board['weight'];
|
||||||
}
|
}
|
||||||
|
|
||||||
array_multisort(
|
array_multisort(
|
||||||
|
$boardWeightValues, SORT_DESC, SORT_NUMERIC, // Sort by weight
|
||||||
$boardActivityValues, SORT_DESC, SORT_NUMERIC, // Sort by number of active posters
|
$boardActivityValues, SORT_DESC, SORT_NUMERIC, // Sort by number of active posters
|
||||||
$boardTotalPostsValues, SORT_DESC, SORT_NUMERIC, // Then, sort by total number of posts
|
$boardTotalPostsValues, SORT_DESC, SORT_NUMERIC, // Then, sort by total number of posts
|
||||||
$response['boards']
|
$response['boards']
|
||||||
@ -159,8 +198,8 @@ array_multisort(
|
|||||||
|
|
||||||
$boardLimit = $search['index'] ? 50 : 100;
|
$boardLimit = $search['index'] ? 50 : 100;
|
||||||
|
|
||||||
$response['omitted'] = $search['index'] ? 0 : count( $response['boards'] ) - $boardLimit;
|
$response['omitted'] = count( $response['boards'] ) - $boardLimit;
|
||||||
$response['boards'] = array_splice( $response['boards'], 0, $boardLimit );
|
$response['boards'] = array_splice( $response['boards'], $search['page'], $boardLimit );
|
||||||
$response['order'] = array_keys( $response['boards'] );
|
$response['order'] = array_keys( $response['boards'] );
|
||||||
|
|
||||||
|
|
||||||
@ -216,9 +255,14 @@ if (count($response['tags']) > 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($tagUsage['users'] as $tagName => $tagUsers) {
|
foreach ($tagUsage['users'] as $tagName => $tagUsers) {
|
||||||
|
if ($weightDepartureFurthest != 0) {
|
||||||
$weightDeparture = abs( $tagUsers - $tagsAvgUsers );
|
$weightDeparture = abs( $tagUsers - $tagsAvgUsers );
|
||||||
$response['tagWeight'][$tagName] = 75 + round( 100 * ( $weightDeparture / $weightDepartureFurthest ), 0);
|
$response['tagWeight'][$tagName] = 75 + round( 100 * ( $weightDeparture / $weightDepartureFurthest ), 0);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
$response['tagWeight'][$tagName] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Include our interpreted search terms. */
|
/* Include our interpreted search terms. */
|
||||||
|
15
boards.php
15
boards.php
@ -36,6 +36,16 @@ $boards_omitted = (int) $searchJson['omitted'];
|
|||||||
$posts_hour = number_format( fetchBoardActivity(), 0 );
|
$posts_hour = number_format( fetchBoardActivity(), 0 );
|
||||||
$posts_total = number_format( $boardResult['posts_total'], 0 );
|
$posts_total = number_format( $boardResult['posts_total'], 0 );
|
||||||
|
|
||||||
|
// This incredibly stupid looking chunk of code builds a query string using existing information.
|
||||||
|
// It's used to make clickable tags for users without JavaScript for graceful degredation.
|
||||||
|
// Because of how it orders tags, what you end up with is a prefix that always ends in tags=x+
|
||||||
|
// ?tags= or ?sfw=1&tags= or ?title=foo&tags=bar+ - etc
|
||||||
|
$tagQueryGet = $_GET;
|
||||||
|
$tagQueryTags = isset($tagQueryGet['tags']) ? $tagQueryGet['tags'] : "";
|
||||||
|
unset($tagQueryGet['tags']);
|
||||||
|
$tagQueryGet['tags'] = $tagQueryTags;
|
||||||
|
$tag_query = "?" . http_build_query( $tagQueryGet ) . ($tagQueryTags != "" ? "+" : "");
|
||||||
|
|
||||||
/* Create and distribute page */
|
/* Create and distribute page */
|
||||||
$config['additional_javascript'] = array(
|
$config['additional_javascript'] = array(
|
||||||
'js/jquery.min.js',
|
'js/jquery.min.js',
|
||||||
@ -45,17 +55,22 @@ $config['additional_javascript'] = array(
|
|||||||
$boardsHTML = Element("8chan/boards-table.html", array(
|
$boardsHTML = Element("8chan/boards-table.html", array(
|
||||||
"config" => $config,
|
"config" => $config,
|
||||||
"boards" => $boards,
|
"boards" => $boards,
|
||||||
|
"tag_query" => $tag_query,
|
||||||
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$tagsHTML = Element("8chan/boards-tags.html", array(
|
$tagsHTML = Element("8chan/boards-tags.html", array(
|
||||||
"config" => $config,
|
"config" => $config,
|
||||||
"tags" => $tags,
|
"tags" => $tags,
|
||||||
|
"tag_query" => $tag_query,
|
||||||
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$searchHTML = Element("8chan/boards-search.html", array(
|
$searchHTML = Element("8chan/boards-search.html", array(
|
||||||
"config" => $config,
|
"config" => $config,
|
||||||
|
"search" => $searchJson['search'],
|
||||||
|
|
||||||
"boards_total" => $boards_total,
|
"boards_total" => $boards_total,
|
||||||
"boards_public" => $boards_public,
|
"boards_public" => $boards_public,
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
'search-tag' : "#search-tag-input",
|
'search-tag' : "#search-tag-input",
|
||||||
'search-title' : "#search-title-input",
|
'search-title' : "#search-title-input",
|
||||||
'search-submit' : "#search-submit",
|
'search-submit' : "#search-submit",
|
||||||
|
|
||||||
|
'tag-link' : ".tag-link"
|
||||||
},
|
},
|
||||||
|
|
||||||
// HTML Templates for dynamic construction
|
// HTML Templates for dynamic construction
|
||||||
@ -50,6 +52,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
lastSearch : {},
|
||||||
|
|
||||||
bind : {
|
bind : {
|
||||||
form : function() {
|
form : function() {
|
||||||
var selectors = boardlist.options.selector;
|
var selectors = boardlist.options.selector;
|
||||||
@ -71,11 +75,17 @@
|
|||||||
'searchSubmit' : $searchSubmit
|
'searchSubmit' : $searchSubmit
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if ($search.length > 0) {
|
if ($search.length > 0) {
|
||||||
// Bind form events.
|
// Bind form events.
|
||||||
$search.on( 'submit', searchForms, boardlist.events.searchSubmit );
|
boardlist.$boardlist
|
||||||
$searchSubmit.prop( 'disabled', false ).on( 'click', searchForms, boardlist.events.searchSubmit );
|
// Tag click
|
||||||
|
.on( 'click', selectors['tag-link'], searchForms, boardlist.events.tagClick )
|
||||||
|
// Form Submission
|
||||||
|
.on( 'submit', selectors['search'], searchForms, boardlist.events.searchSubmit )
|
||||||
|
// Submit click
|
||||||
|
.on( 'click', selectors['search-submit'], searchForms, boardlist.events.searchSubmit );
|
||||||
|
|
||||||
|
$searchSubmit.prop( 'disabled', false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -83,6 +93,7 @@
|
|||||||
build : {
|
build : {
|
||||||
boardlist : function(data) {
|
boardlist : function(data) {
|
||||||
boardlist.build.boards(data['boards'], data['order']);
|
boardlist.build.boards(data['boards'], data['order']);
|
||||||
|
boardlist.build.lastSearch(data['search']);
|
||||||
boardlist.build.tags(data['tags']);
|
boardlist.build.tags(data['tags']);
|
||||||
|
|
||||||
},
|
},
|
||||||
@ -101,12 +112,10 @@
|
|||||||
boardlist.build.board( row, col ).appendTo( $row );
|
boardlist.build.board( row, col ).appendTo( $row );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
if( index >= 100 ) return false;
|
|
||||||
|
|
||||||
$row.appendTo( $body );
|
$row.appendTo( $body );
|
||||||
} );
|
} );
|
||||||
},
|
},
|
||||||
board : function( row, col ) {
|
board : function(row, col) {
|
||||||
var $col = $(col),
|
var $col = $(col),
|
||||||
column = $col.attr('data-column'),
|
column = $col.attr('data-column'),
|
||||||
value = row[column]
|
value = row[column]
|
||||||
@ -150,10 +159,10 @@
|
|||||||
return $cell;
|
return $cell;
|
||||||
},
|
},
|
||||||
boardcell : {
|
boardcell : {
|
||||||
'meta' : function( row, value ) {
|
'meta' : function(row, value) {
|
||||||
return $( boardlist.options.template['board-datum-lang'] ).text( row['locale'] );
|
return $( boardlist.options.template['board-datum-lang'] ).text( row['locale'] );
|
||||||
},
|
},
|
||||||
'uri' : function( row, value ) {
|
'uri' : function(row, value) {
|
||||||
var $link = $( boardlist.options.template['board-datum-uri'] ),
|
var $link = $( boardlist.options.template['board-datum-uri'] ),
|
||||||
$sfw = $( boardlist.options.template['board-datum-' + (row['sfw'] == 1 ? "sfw" : "nsfw")] );
|
$sfw = $( boardlist.options.template['board-datum-' + (row['sfw'] == 1 ? "sfw" : "nsfw")] );
|
||||||
|
|
||||||
@ -172,8 +181,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
tags : function(data) {
|
lastSearch : function(search) {
|
||||||
|
return boardlist.lastSearch = {
|
||||||
|
'lang' : search.lang === false ? "" : search.lang,
|
||||||
|
'page' : search.page,
|
||||||
|
'tags' : search.tags === false ? "" : search.tags.join(" "),
|
||||||
|
'time' : search.time,
|
||||||
|
'title' : search.title === false ? "" : search.title,
|
||||||
|
'sfw' : search.nsfw ? 0 : 1
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
tags : function(data) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -181,7 +200,33 @@
|
|||||||
searchSubmit : function(event) {
|
searchSubmit : function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
var $boardlist = event.data.boardlist,
|
boardlist.submit( {
|
||||||
|
'lang' : event.data.searchLang.val(),
|
||||||
|
'tags' : event.data.searchTag.val(),
|
||||||
|
'title' : event.data.searchTitle.val(),
|
||||||
|
'sfw' : event.data.searchSfw.prop('checked') ? 1 : 0
|
||||||
|
} );
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
tagClick : function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
var $this = $(this),
|
||||||
|
$input = $( boardlist.options.selector['search-tag'] );
|
||||||
|
|
||||||
|
$input
|
||||||
|
.val( ( $input.val() + " " + $this.text() ).replace(/\s+/g, " ").trim() )
|
||||||
|
.trigger( 'change' )
|
||||||
|
.focus();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
submit : function( parameters ) {
|
||||||
|
var $boardlist = boardlist.$boardlist,
|
||||||
$boardbody = $( boardlist.options.selector['board-body'], $boardlist ),
|
$boardbody = $( boardlist.options.selector['board-body'], $boardlist ),
|
||||||
$boardload = $( boardlist.options.selector['board-loading'], $boardlist );
|
$boardload = $( boardlist.options.selector['board-loading'], $boardlist );
|
||||||
|
|
||||||
@ -190,21 +235,12 @@
|
|||||||
|
|
||||||
$.get(
|
$.get(
|
||||||
"/board-search.php",
|
"/board-search.php",
|
||||||
{
|
parameters,
|
||||||
'lang' : event.data.searchLang.val(),
|
|
||||||
'tags' : event.data.searchTag.val(),
|
|
||||||
//'time' : event.data.searchTag.val(),
|
|
||||||
'title' : event.data.searchTitle.val(),
|
|
||||||
'sfw' : event.data.searchSfw.prop('checked') ? 1 : 0
|
|
||||||
},
|
|
||||||
function(data) {
|
function(data) {
|
||||||
$boardload.hide();
|
$boardload.hide();
|
||||||
boardlist.build.boardlist( $.parseJSON(data) );
|
boardlist.build.boardlist( $.parseJSON(data) );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
init : function( target ) {
|
init : function( target ) {
|
||||||
@ -217,7 +253,6 @@
|
|||||||
if ($boardlist.length > 0 ) {
|
if ($boardlist.length > 0 ) {
|
||||||
$( boardlist.options.selector['board-loading'], $boardlist ).hide();
|
$( boardlist.options.selector['board-loading'], $boardlist ).hide();
|
||||||
|
|
||||||
|
|
||||||
boardlist.$boardlist = $boardlist;
|
boardlist.$boardlist = $boardlist;
|
||||||
boardlist.bind.form();
|
boardlist.bind.form();
|
||||||
}
|
}
|
||||||
|
@ -8,16 +8,16 @@
|
|||||||
|
|
||||||
<div class="board-list">
|
<div class="board-list">
|
||||||
<aside class="search-container col col-2">
|
<aside class="search-container col col-2">
|
||||||
<form id="search-form" class="box" method="get" target="/board-search.php">
|
<form id="search-form" class="box" method="get" action="/boards.php">
|
||||||
<h2 class="box-title">Search</h2>
|
<h2 class="box-title">Search</h2>
|
||||||
|
|
||||||
<div class="board-search box-content">
|
<div class="board-search box-content">
|
||||||
<label class="search-item search-sfw">
|
<label class="search-item search-sfw">
|
||||||
<input type="checkbox" id="search-sfw-input" name="sfw" value="1" /> Hide NSFW boards
|
<input type="checkbox" id="search-sfw-input" name="sfw" value="1" {% if not search.nsfw %}checked="checked"{% endif %} /> Hide NSFW boards
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div class="search-item search-title">
|
<div class="search-item search-title">
|
||||||
<input type="text" id="search-title-input" name="title" name="title" value="" placeholder="Search titles..." />
|
<input type="text" id="search-title-input" name="title" name="title" value="{{search.title}}" placeholder="Search titles..." />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="search-item search-lang">
|
<div class="search-item search-lang">
|
||||||
@ -34,7 +34,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="search-item search-tag">
|
<div class="search-item search-tag">
|
||||||
<input type="text" id="search-tag-input" name="tags" value="" placeholder="Search tags..." />
|
<input type="text" id="search-tag-input" name="tags" value="{{ search.tags|join(' ') }}" placeholder="Search tags..." />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="search-item search-submit">
|
<div class="search-item search-submit">
|
||||||
|
@ -9,6 +9,6 @@
|
|||||||
<td class="board-pph"><div class="board-cell">{{board['pph']}}</td>
|
<td class="board-pph"><div class="board-cell">{{board['pph']}}</td>
|
||||||
<td class="board-max"><div class="board-cell">{{board['posts_total']}}</td>
|
<td class="board-max"><div class="board-cell">{{board['posts_total']}}</td>
|
||||||
<td class="board-unique"><div class="board-cell">{{board['active']}}</td>
|
<td class="board-unique"><div class="board-cell">{{board['active']}}</td>
|
||||||
<td class="board-tags"><div class="board-cell">{% for tag in board.tags %}<a class="tag-link" href="#">{{ tag }}</a>{% endfor %}</div></td>
|
<td class="board-tags"><div class="board-cell">{% for tag in board.tags %}<a class="tag-link" href="{{ tag_query }}{{ tag }}">{{ tag }}</a>{% endfor %}</div></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
@ -1,5 +1,5 @@
|
|||||||
{% for tag, weight in tags %}
|
{% for tag, weight in tags %}
|
||||||
<li class="tag-item">
|
<li class="tag-item">
|
||||||
<a class="tag-link" href="#" style="font-size: {{weight}}%;">{{tag}}</a>
|
<a class="tag-link" href="{{ tag_query }}{{ tag }}" style="font-size: {{weight}}%;">{{tag}}</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
Loading…
x
Reference in New Issue
Block a user