mirror of
https://github.com/vichan-devel/vichan.git
synced 2024-11-30 18:24:29 +01:00
- 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(
|
||||
'lang' => false,
|
||||
'nsfw' => true,
|
||||
'page' => 0,
|
||||
'tags' => false,
|
||||
'time' => ( (int)( time() / 3600 ) * 3600 ) - 3600,
|
||||
'title' => false,
|
||||
@ -37,6 +38,15 @@ if (isset( $_GET['sfw'] ) && $_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)?
|
||||
if (isset( $_GET['lang'] ) && $_GET['lang'] != "" && isset($languages[$search['lang']])) {
|
||||
$search['lang'] = $_GET['lang'];
|
||||
@ -44,7 +54,8 @@ if (isset( $_GET['lang'] ) && $_GET['lang'] != "" && isset($languages[$search['l
|
||||
|
||||
// Include what tag?
|
||||
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?
|
||||
@ -73,6 +84,31 @@ foreach ($boards as $board) {
|
||||
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.
|
||||
$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.
|
||||
foreach ($response['boards'] as $boardUri => &$board) {
|
||||
// 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] );
|
||||
}
|
||||
// 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.
|
||||
$boardActivityValues = array();
|
||||
$boardTotalPostsValues = array();
|
||||
$boardWeightValues = array();
|
||||
|
||||
foreach ($response['boards'] as $boardUri => &$board) {
|
||||
$boardActivityValues[$boardUri] = (int) $board['active'];
|
||||
$boardTotalPostsValues[$boardUri] = (int) $board['posts_total'];
|
||||
$boardWeightValues[$boardUri] = (int) $board['weight'];
|
||||
}
|
||||
|
||||
array_multisort(
|
||||
$boardWeightValues, SORT_DESC, SORT_NUMERIC, // Sort by weight
|
||||
$boardActivityValues, SORT_DESC, SORT_NUMERIC, // Sort by number of active posters
|
||||
$boardTotalPostsValues, SORT_DESC, SORT_NUMERIC, // Then, sort by total number of posts
|
||||
$response['boards']
|
||||
@ -159,8 +198,8 @@ array_multisort(
|
||||
|
||||
$boardLimit = $search['index'] ? 50 : 100;
|
||||
|
||||
$response['omitted'] = $search['index'] ? 0 : count( $response['boards'] ) - $boardLimit;
|
||||
$response['boards'] = array_splice( $response['boards'], 0, $boardLimit );
|
||||
$response['omitted'] = count( $response['boards'] ) - $boardLimit;
|
||||
$response['boards'] = array_splice( $response['boards'], $search['page'], $boardLimit );
|
||||
$response['order'] = array_keys( $response['boards'] );
|
||||
|
||||
|
||||
@ -216,9 +255,14 @@ if (count($response['tags']) > 0) {
|
||||
}
|
||||
|
||||
foreach ($tagUsage['users'] as $tagName => $tagUsers) {
|
||||
if ($weightDepartureFurthest != 0) {
|
||||
$weightDeparture = abs( $tagUsers - $tagsAvgUsers );
|
||||
$response['tagWeight'][$tagName] = 75 + round( 100 * ( $weightDeparture / $weightDepartureFurthest ), 0);
|
||||
}
|
||||
else {
|
||||
$response['tagWeight'][$tagName] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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_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 */
|
||||
$config['additional_javascript'] = array(
|
||||
'js/jquery.min.js',
|
||||
@ -45,17 +55,22 @@ $config['additional_javascript'] = array(
|
||||
$boardsHTML = Element("8chan/boards-table.html", array(
|
||||
"config" => $config,
|
||||
"boards" => $boards,
|
||||
"tag_query" => $tag_query,
|
||||
|
||||
)
|
||||
);
|
||||
|
||||
$tagsHTML = Element("8chan/boards-tags.html", array(
|
||||
"config" => $config,
|
||||
"tags" => $tags,
|
||||
"tag_query" => $tag_query,
|
||||
|
||||
)
|
||||
);
|
||||
|
||||
$searchHTML = Element("8chan/boards-search.html", array(
|
||||
"config" => $config,
|
||||
"search" => $searchJson['search'],
|
||||
|
||||
"boards_total" => $boards_total,
|
||||
"boards_public" => $boards_public,
|
||||
|
@ -22,6 +22,8 @@
|
||||
'search-tag' : "#search-tag-input",
|
||||
'search-title' : "#search-title-input",
|
||||
'search-submit' : "#search-submit",
|
||||
|
||||
'tag-link' : ".tag-link"
|
||||
},
|
||||
|
||||
// HTML Templates for dynamic construction
|
||||
@ -50,6 +52,8 @@
|
||||
}
|
||||
},
|
||||
|
||||
lastSearch : {},
|
||||
|
||||
bind : {
|
||||
form : function() {
|
||||
var selectors = boardlist.options.selector;
|
||||
@ -71,11 +75,17 @@
|
||||
'searchSubmit' : $searchSubmit
|
||||
};
|
||||
|
||||
|
||||
if ($search.length > 0) {
|
||||
// Bind form events.
|
||||
$search.on( 'submit', searchForms, boardlist.events.searchSubmit );
|
||||
$searchSubmit.prop( 'disabled', false ).on( 'click', searchForms, boardlist.events.searchSubmit );
|
||||
boardlist.$boardlist
|
||||
// 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 : {
|
||||
boardlist : function(data) {
|
||||
boardlist.build.boards(data['boards'], data['order']);
|
||||
boardlist.build.lastSearch(data['search']);
|
||||
boardlist.build.tags(data['tags']);
|
||||
|
||||
},
|
||||
@ -101,12 +112,10 @@
|
||||
boardlist.build.board( row, col ).appendTo( $row );
|
||||
} );
|
||||
|
||||
if( index >= 100 ) return false;
|
||||
|
||||
$row.appendTo( $body );
|
||||
} );
|
||||
},
|
||||
board : function( row, col ) {
|
||||
board : function(row, col) {
|
||||
var $col = $(col),
|
||||
column = $col.attr('data-column'),
|
||||
value = row[column]
|
||||
@ -150,10 +159,10 @@
|
||||
return $cell;
|
||||
},
|
||||
boardcell : {
|
||||
'meta' : function( row, value ) {
|
||||
'meta' : function(row, value) {
|
||||
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'] ),
|
||||
$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) {
|
||||
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 ),
|
||||
$boardload = $( boardlist.options.selector['board-loading'], $boardlist );
|
||||
|
||||
@ -190,21 +235,12 @@
|
||||
|
||||
$.get(
|
||||
"/board-search.php",
|
||||
{
|
||||
'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
|
||||
},
|
||||
parameters,
|
||||
function(data) {
|
||||
$boardload.hide();
|
||||
boardlist.build.boardlist( $.parseJSON(data) );
|
||||
}
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
init : function( target ) {
|
||||
@ -217,7 +253,6 @@
|
||||
if ($boardlist.length > 0 ) {
|
||||
$( boardlist.options.selector['board-loading'], $boardlist ).hide();
|
||||
|
||||
|
||||
boardlist.$boardlist = $boardlist;
|
||||
boardlist.bind.form();
|
||||
}
|
||||
|
@ -8,16 +8,16 @@
|
||||
|
||||
<div class="board-list">
|
||||
<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>
|
||||
|
||||
<div class="board-search box-content">
|
||||
<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>
|
||||
|
||||
<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 class="search-item search-lang">
|
||||
@ -34,7 +34,7 @@
|
||||
</div>
|
||||
|
||||
<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 class="search-item search-submit">
|
||||
|
@ -9,6 +9,6 @@
|
||||
<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-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>
|
||||
{% endfor %}
|
@ -1,5 +1,5 @@
|
||||
{% for tag, weight in tags %}
|
||||
<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>
|
||||
{% endfor %}
|
Loading…
Reference in New Issue
Block a user