Does anyone know of a good resource on how to create the hyperlink numbers at the bottom of a results page as search engines do to load the next number of results?
The page would load the first 10 results. And then if you click on the number, it loads corresponding results in that 10 number range.
Example:
0-10 -> show no numbers
11-20 -> show 1, 2
21-30 -> 1, 2, 3
up to 50
anything more than 50 does 1,2,3,4,5.....67 [last number].
My thoughts so far (I'm doing this in PHP/mysqli but the logic is more important than the code):
$total = mysqli_num_rows($result) //total number of reqults from sql query
if ($total>10) {
$last = intval($total/10) + 1 //get the last number of the results
if($last <= 5){
for ($i, $i<$last, $i++){
//print the numbers as hyperlinks
} else {
//print 1 through 5 ... then $last
}
}
This though is static from only 1-5...last number while the search engines have it so if you click on the number, it remembers that number and bases the new logic on it. So if I click on the 5 in my formula, it should change to something like:
[previous] 3,4,5,6,7....67 [next]
And then I would just pass the number to the page itself again and limit the results based on what number was passed. Any suggestions also on the best way to pass the info?
You are looking for a pagination script. Visit this link The page is in Arabic but forth post is of pagination and you can download source for english or arabic version of pagination
Basically, you need two values to create a pagination, a limit and a offset.
1.The limit is the amount of items your are displaying at the same time.
2.The offset is from where you started your query.
So, let's say you have 5 items in each page and 25 items total.
In your query, you have to limit 5,0 (the amount of items and the position the query will start).
Now, if you divide 5(limit)/25(total) and you'll get 5 (amount of pages).
Now in page 0 (the start) you can get the offset by multiplying the page number with the limit, so 0 (page) * 5 (limit) gives you 0 (in the first page you start from the offset 0).
Now in the 3rd page, you multiply 3(page) * 5 (limit) it gives you 15, which means in page 3 (or four if you take into account that you actually started at page 0) you will display from offset 16 to 20.
Finally in page 4 (which to your users will be page 5 because they started at page 1, not page 0) you will display from offset 21 to 25 which are all the items in your query.
Related
Another question on SO revealed that pageTokens are identical for different searches, provided that the page number and maxResults settings are the same.
Version 2 of the API let you go to any arbitrary page by setting a start position, but v3 only provides next and previous tokens. There's no jumping from page 1 to page 5, even if you know there are 5 pages of results.
So how do we work around this?
A YouTube pageToken is six characters long. Here's what I've been able to determine about the format:
char 1: Always 'C' that I've seen.
char 2-3: Encoded start position
char 4-5: Always 'QA' that I've seen.
char 6: 'A' means list items in a position greater than or equal to the start position. 'Q' means list items before the start position.
Due to the nature of character 6, there are two different ways to represent the same page. Given maxResults=1, page 2 can be reached by setting the page token to either "CAEQAA" or "CAIQAQ". The first one means to start at result number 2 (represented by characters 2-3 "AE") and list 1 item. The second means to return one item before result number 3 (represented by characters 2-3 "AI".
Characters 2-3 are a strange base 16 encoding.
Character 3 uses a list from A-Z, then a-z, then 0-9 and increments by 4 in the list for each increase of 1. The series is A,E,I,M,Q,U,Y,c,g,k,o,s,w,0,4,8. Character 2 goes from A to B to C to D and so on. For my purposes, I'm not working with large result sets, so I haven't bothered to see what happens to the second character beyond a couple hundred results. Perhaps someone working with larger sets will provide an update as to how character 2 behaves after that.
Since the string only contains a start position and an option for ">=" or "<", the same string is used in multiple cases. For instance, with 2 results per page, the start position of the second page is result 3. The pageToken for this is "CAIQAA". This is identical to the token for the third page with one result per page.
Since I'm primarily a php person, here's the function I'm using to get the pageToken for a given page:
function token($limit, $page) {
$start = 1 + ($page - 1) * $limit;
$third_chars = array_merge(
range("A","Z",4),
range("c","z",4),
range(0,9,4));
return 'C'.
chr(ord('A') + floor($start / 16)).
$third_chars[($start % 16) - 1].
'QAA';
}
$limit = 1;
echo "With $limit result(s) per page...".PHP_EOL;
for ($i = 1; $i < 6; ++$i) {
echo "The token for page $i is ".token($limit, $i).PHP_EOL;
}
Please test this function in your project and update the rest of us if you find a flaw or an enhancement since YouTube hasn't provided us with an easy way to do this.
Edit: The page token sequence for YouTube API v3 has been changed, and this system will no longer work. For an example of the most up-to-date and working page tokens, see this page.
YouTube's pagetokens can be treated as indices.
Pagetokens for the first 1000 items can be found here.
Pagetokens for every 10th item in range(1, 100000) can be found here.
The highest available pagetoken is "CJ-NBhAA" which points to the 100.000th item with position 99.999.
The highest possible value for maxresults is 50.
Use pagetoken to specify a starting point and maxresults to specify the number of items.
Examples:
1st item
https://www.googleapis.com/youtube/v3/playlistItems?part=id%2Csnippet&playlistId=<PLAYLISTID>&key=<APIKEY>&maxResults=1&pageToken=CAAQAA
555th item
https://www.googleapis.com/youtube/v3/playlistItems?part=id%2Csnippet&playlistId=<PLAYLISTID>&key=<APIKEY>&maxResults=1&pageToken=CKoEEAA
99999th item
https://www.googleapis.com/youtube/v3/playlistItems?part=id%2Csnippet&playlistId=<PLAYLISTID>&key=<APIKEY>&maxResults=1&pageToken=CJ6NBhAA
10 items starting at 10th item
https://www.googleapis.com/youtube/v3/playlistItems?part=id%2Csnippet&playlistId=<PLAYLISTID>&key=<APIKEY>&maxResults=10&pageToken=CAkQAA
30 items starting at 555th item
https://www.googleapis.com/youtube/v3/playlistItems?part=id%2Csnippet&playlistId=<PLAYLISTID>&key=<APIKEY>&maxResults=30&pageToken=CKoEEAA
50 items starting at 9999th item
https://www.googleapis.com/youtube/v3/playlistItems?part=id%2Csnippet&playlistId=<PLAYLISTID>&key=<APIKEY>&maxResults=50&pageToken=CI9OEAA
Using ^ Quihico's files as a reference point, I had a little fun writing an enhancement to the previous poster's pageToken generator, in JS. If my assumption is correct about how the 4000s place encoding varies past N >= 98304, it should be able to construct a pageToken for a page starting with Nth item, provided N in [0, 4194304). It's only tested up to N = 99999, so YMMV.
Link here: https://github.com/aricearice/youtube-page-token/blob/master/index.js
An addendum to thatthatisis's answer, the linked token list is specifically for maxResults=10. I exported a complete list for the currently maximum allowed value for maxResults, 50:
https://github.com/Koushakur/randomStuff/blob/main/YouTube%20API%20pageTokens%20for%20maxResults%3D50.txt
I call it 'complete' because the API just looped around after the last token in the list to the first page even though I used a upload playlist of a channel with a million videos on it to grab the tokens, so it seems like the maximum size of a playlist is about 20700 videos.
I need to do pagination for table contain the following:
id.
name.
type (this contains: bad, good, great).
I need to order the result depending on type, first to appear 'great' then 'good' and last 'bad'. For example: I have 36 rows with type 'great', 25 with type 'good' and 13 with type 'bad' (total number of rows is 74), and I'm going to display 10 at each page. So at page 4 there will be 6 of type 'great' and 4 of type 'good'.
How to do such pagination?
On click of a button (arrow, , submit input, whatever suits you) send a parameter via get or post with the page number (starting with 0).
On your server side get the page number that you sent, check if it's valid and clean it off hazardous stuff (like injections of all sorts). Multiply it by some "pagesize" and then query the database for a range of records (order by type, id).
Example: 74 records, page 4, you pass page=3 as GET parameter and set it to some variable ($page), multiply it by page size and put into a query with offset and limit:
SELECT * FROM table
ORDER BY type DESC, id
LIMIT 10 OFFSET 30
where offset is calculated as $page * $pageSize, and limit is $pageSize. As a result you get 10 records from the range 31-40, sorted by type.
In this concrete example you can just alphabetically sort your types descending (since 'great' > 'good' > 'bad'), but you might need more advanced sorting for more different types.
On my search engine I get results via xml from blekko.com
I use: http://blekko.com/ws/?q=google/rss
And adding: &p= *number*
I can get different pages of results, e.g.
Page 1, 1 - 15 results
Page 2, 15 - 30 results
Like at the bottom of google, however I also get a number of total results
With those two (total & page number) is there any way to generate the right amount of links at the bottom for a next button, page1 results, page 2 results ect...
$count is the total and there are 15 results per page
If I understand you correctly you want something like:
for($i; $i<10 && $i<$totalPages; $i++)
{
echo ''.$i.'';
}
?
Not sure of what you want to do but usually to create links to different pages of results you need the total number of results and the nb of results you want to display per page. You then make a simple division to get the number of pages.
Trying to teach myself the concept of how to calculate the indexes for pagination, I have found the following text:
Say for example that we have per page equals to 10, so it will be ten
items per page. Once again our calculation for offset is per page,
which is ten, times the current page, minus 1. If the current page is
1, that calculation works out so that offset is 0, and that would mean
that records 1 through 10 would be 10, and that would mean that
records 11 through 20 would be returned
Maybe I'm looking at it the wrong way, but I don't get it.
The text states that using an example of 10 items per page, and we're on the first page, the formula should be:
10 * 1 - 1 -> this by my brain cramp should equal 9, but the text says it's 0
The next example they use is: 10 * 2 - 1 = 10, using normal math, is that not 19??
there's obviously something I'm missing here.
What they mean is
10 * (1-1) = 0
and
10 * (2-1) = 10
In the end this boils down to the fact that people count from 1 (the first page is page 1), but the offset starts at 0. So if you have a page-number, you need to lower it by one to get the offset number (the first page is 1, the first offset is 0 ).
THat means you first subtract (hence the brackets) and then multiply. The text is just a little bit confusing.
I have a given number of potential posts. We don't know how many there are but the system is set up to show 12 per page. Along the bottom I would like it to display the number of pages.
So first if we get the posts:
<?php $pages = get_posts('category_name=news'); ?>
Now what we want to do is
work out how many posts it has found
divide that number by 12
round that number up to the nearest whole number (UP never down)
divide that number by 1 and give how many times 1 goes into it.
thus giving as many page numbers as needed.
The ideas is to have them lined up as 1 | 2 | 3 | 4 | 5 etc..
Any ideas?
You're over thinking it. If you know the number of results and the max number of results per page, then you know how many pages you need. I suppose this is WordPress because you've used get_posts, so that should return an array containing the posts, so:
<?php
$max_per_page = 12; //Max results per page
$posts = get_posts('category_name=news');
$total_posts = count($posts); //Total number of posts returned
$pages = ceil($total_posts / $max_per_page);
for($i = 1;$i <= $pages;$i++)
{
echo '' . $i . ''; //Or whatever the link needs to be
if($i != $pages)
{
echo "|"
}
}
?>
work out how many posts it has found
SELECT COUNT(*) FROM *table* WHERE *conditions*...
divide that number by 12
SELECT COUNT(*)/12 AS num_pages FROM *table* WHERE *conditions*...
OR
$count = mysql_query(*see #1*)/12.0; // NOT JUST 12!
round that number up to the nearest whole number (UP never down)
$count = ceil($count);
divide that number by 1 and give how many times 1 goes into it.
REALLY?? DIVIDING ANY NUMBER BY 1 RETURNS ITSELF!
thus giving as many page numbers as needed.
Not really. How would you know what particular page the user is currently on? How do you plan on actually paginating posts? If the posts are already populated, you are wasting 1-2 queries every time, just for your pagination.
You are basically trying to make pagination, but without knowing a lot of SQL, you're better off using an existing solution (or at least re-factor the existing code to limit queries)