I have a small script that displays blog posts from a text file, how can I add pagination so that it only shows 5 blog posts at a time?
Here is the script:
<html>
<head>
<title>blog</title>
</head>
<body>
<?php
$mode = 0;
if ($mode == 0) { $opFile = "blogfile.txt"; }
$fp = fopen($opFile,"r") or die("Error Reading File");
$data = fread($fp, filesize($opFile));
fclose($fp);
$line = explode("\n", $data);
$i=count($line);
for ($n=0 ; $n < $i-1 ; $n++ ) {
$blog = explode("|", $line[$n]);
if (isset($blog[0]))
{
echo "<div class=\"blog-post\">";
echo "<p class=\"blog-title\">".$blog[1]."</p>";
echo "<p class=\"blog-message\">".$blog[2]."</p>";
echo "<p class=\"blog-date\">Posted: " .$blog[0]."</p>";
echo "<div style=\"clear: both;\"></div>";
echo "</div>";
}
}
?>
</body>
</html>
And here is the text file:
Feb 17 2010|Title|Blog post content here|[end]
Feb 17 2010|Title|Blog post content here|[end]
Feb 17 2010|Title|Blog post content here|[end]
Feb 17 2010|Title|Blog post content here|[end]
Any help is greatly appreciated!
Something like this:
<html>
<head>
<title>blog</title>
</head>
<body>
<?php
$POSTS_PER_PAGE = 10;
//Not sure what this is for, but I left it?
$mode = 0;
if ($mode == 0) { $opFile = "blogfile.txt"; }
//Explode the textfile into lines
$lines = file($opFile);
$posts = array();
foreach($lines as $line) {
//Ignore blank lines
if($line != "") {
//Explode each non-empty line
$post = explode("|", $line);
//Store the blog post
array_push($posts, $post)
}
}
//Output the pagination links
echo "<div class=\"blog-pagination\">";
for($i = 1; $i < ceil(count($posts) / $POSTS_PER_PAGE; $i++) {
echo '' + $i + ' ';
}
echo "</div>";
//Assume the user wants the first page if it's not specified
if(!isset($_GET['page'])) {
$_GET['page'] = 1;
}
//Figure out the first and last posts on this page
$first_post = ($_GET['page'] - 1) * $POSTS_PER_PAGE;
$last_post = $_GET['page'] * $POSTS_PER_PAGE - 1;
//Display the requested posts
for($i = $first_post; $i <= $last_post; $i++) {
echo "<div class=\"blog-post\">";
echo "<p class=\"blog-title\">".$blog[1]."</p>";
echo "<p class=\"blog-message\">".$blog[2]."</p>";
echo "<p class=\"blog-date\">Posted: " .$blog[0]."</p>";
echo "<div style=\"clear: both;\"></div>";
echo "</div>";
}
?>
(This is completely untested, but hopefully you can take it from here!)
This worked in my tests:
define('MAX_PER_PAGE',10);
// sanity checks for per-page and page index
$numPosts = ctype_digit((string)$_GET['perpage']) ? $_GET['perpage'] : 5;
$ostart = $start = max(1, ctype_digit((string)$_GET['page']) ? $_GET['page'] : 1) - 1;
$mode = 0;
if ($mode == 0) {
$file = "blogfile.txt";
}
// read the file into an array, strip newlines and ignore empty lines
file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES | FILE_TEXT);
// sort array (see custom function at bottom)
usort($line, 'blogsort');
$lines = count($line);
// get total number of pages
$numPages = ceil($lines / $numPosts);
// additional sanity checks (also sets $ostart if it was invalid; used later)
$numPosts = min(MAX_PER_PAGE, max(1, $numPosts));
if ($start * $numPosts > $lines ) {
$ostart = $start = max(0, $lines - $numPosts);
}
else {
$start *= $numPosts;
}
// Only grab the part of the array we need
$sliced = array_slice($line, $start, $numPosts);
// loop through posts, but break early if we run out
for ($n = 0; $n < $numPosts && isset($sliced[$n]); $n++ ) {
$blog = explode("|", $sliced[$n]);
if (isset($blog[0])) {
echo "<div class=\"blog-post\">\n",
"<p class=\"blog-title\">{$blog[1]}</p>\n",
"<p class=\"blog-message\">{$blog[2]}</p>\n",
"<p class=\"blog-date\">Posted: {$blog[0]}</p>\n",
"<div style=\"clear: both;\"></div>\n",
"</div>\n\n";
}
}
// back link
if ($ostart > 0) {
echo "← Older";
}
else {
echo "None Older";
}
echo " || ";
// forward link
if ($ostart + 1 < $numPages) {
$next = $ostart + 2;
echo "Newer →";
}
else {
echo "None Newer";
}
function blogsort($a, $b) {
$dateA = strtotime(substr($a, 0, strpos($a, '|')));
$dateB = strtotime(substr($b, 0, strpos($b, '|')));
if ($dateA == $dateB) {
return 0;
}
elseif ($dateA > $dateB) {
return -1;
}
else {
return 1;
}
}
I want to show a pagination which only shows the recent and next 3 pages, but I can't get it working.
Here's my current code:
$stmt = MySQL::connection3()->prepare("SELECT COUNT(ID) AS TOTAL FROM products");
$stmt->execute();
$row = $stmt->fetch();
$total_pages = ceil(intval($row["TOTAL"]) / $results_per_page);
foreach (range(1, $total_pages) as $i) {
if ($i == $page) {
?>
<li class="page-item active">
<?php echo $i ?>
</li>
<?php
} else {
?>
<li class="page-item">
<?php echo $i ?>
</li>
<?php
}
}
Thanks!
I create this example you can run and adapt with your code:
<style>.active{color:green!important}</style>
<?php
echo get_pagination_links('10','100');
function get_pagination_links($current_page, $total_pages)
{
$links = "";
if ($total_pages >= 1 && $current_page <= $total_pages) {
$i = max(2, $current_page - 3);
for (; $i < min($current_page + 4, $total_pages); $i++) {
if($i==$current_page){
$links .= "<li class='page-item active'><a href='?page=$i;' class='page-link'>$i</a></li>";
}else{
$links .= "<li class='page-item'><a href='?page=$i;' class='page-link'>$i</a></li>";
}
}
return $links;
}
}
?>
Output:
7-8-9-10-11-12-13
obviously I didn't connect a database and therefore I used a static result
So I have a simple pagination system on my website. But there's a problem with my calculation for the next page. whenever the page is on page 2 the next page is 13 instead of 3. I have tested the calculation and it always comes out with 3 as result. Here is my code:
<?php
$applied_filters = array("parent" => null, "child" => null);
if(isset($_GET['cat'])) {
$applied_filters["parent"] = $_GET['cat'];
if(isset($_GET['sub']))
$applied_filters["child"] = $_GET['sub'];
}
if(isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = 1;
}
$products_per_page = 9;
$start_from = ($page-1) * $products_per_page;
$pagination_url = "winkel.php?";
if($applied_filters["parent"] != null) {
$pagination_url .= "cat=" . $applied_filters["parent"];
if($applied_filters["child"] != null) {
$pagination_url .= "&sub=" . $applied_filters["child"] . "&page=";
} else {
$pagination_url .= "&page=";
}
} else {
$pagination_url .= "page=";
}
echo $page . '<br>'; // shows 2
$nextpage = $page + 1; //shows 3
echo $nextpage;
?>
<ul class="pagination">
<?php if($page > 1) { ?>
<li>«
</li>
<?php } ?>
<li class="active"><?= $page ?>
</li>
<?php if($page < $max_pages) { echo $nextpage; // shows 3?>
<li>»
</li>
<?php } ?>
I also have some URL code for the filters on my website:
<?php
// link filters
if(isset($_GET['cat'])) {
if(isset($_GET['cat']) && isset($_GET['sub'])) {
if($_GET['cat'] != "alles")
$result_products = $db->get_by_cat("products", $_GET['cat'], $_GET['sub'], $start_from, $products_per_page);
} else if (isset($_GET['cat'])) {
if($_GET['cat'] != "alles")
$result_products = $db->get_by_cat("products", $_GET['cat'], null, $start_from, $products_per_page);
}
}
if(isset($_POST['clearbrand'])) {
unset($_POST['brandfilter']);
unset($_POST['applybrand']);
}
$filtered_brands = null;
if(isset($_POST['brandfilter'])) $filtered_brands = $_POST['brandfilter'];
// form filters
if(isset($_POST['applybrand'])) {
if(isset($_GET['cat'])) {
$result_products = $db->get_by_checkbox("products", "brand", $_POST['brandfilter'], $_GET);
} else {
$result_products = $db->get_by_checkbox("products", "brand", $_POST['brandfilter']);
}
}
?>
So, does anybody know why my pagination counts from 2 to 13?
Thanks in advance
Your problem is here:
<?php if($page > 1) { ?>
<li>«</li>
<?php } ?>
<li class="active"><?= $page ?></li>
<?php if($page < $max_pages) { echo $nextpage; // shows 3?>
<li>»</li>
<?php } ?>
If $page is greater than 1 (which it is on page 2), you add $page - 1 to the $pagination_url, basically putting a "1" at the end.
Then, in the second if statement, if $page is less than $max_pages, you also add $nextpage (which is 3) to the $pagination_url, putting a "3" after the "1" you added before. Therefore, $pagination_url will now have "13" at the end.
You'll want to change this to:
<?php if($page > 1) { ?>
<li>«</li>
<?php } ?>
<li class="active"><?= $page ?></li>
<?php if($page < $max_pages) { echo $nextpage; // shows 3?>
<li>»</li>
<?php } ?>
I am showing images in php in ul list. I want to show 5 li in my ul then 2 li and after that again 5 li.I am using this code but it is showing 5 li every row.
<?php
$data = array(1,2,3,4,5,6,7,8,9,10,11,12);
$break_after = 5;
$counter = 0;
$totalNumber = count($data);
foreach ($data as $item)
{
if ($counter % $break_after == 0)
{
echo '<ul>';
}
echo '<li>'.$item.'</li>';
if ($counter % $break_after == ($break_after-1) || $counter == $totalNumber-1) {
echo '</ul>';
}
++$counter;
}
dfff
fdfddf
fdfd
ffd
fdfd
fddf
dfdf
fddf
dfdf
dfdf
fddf
fddf
fdfd
fddf
fddf
fdfd
fddf
Hope this solution might help you :
When you want a break after 5,2,5 Y not take that an array array(5,2,5) instead of just break_after=5. break_after=5 will breake the ul at every 5 intervals. I have some change in logic for you :
$data = array(1,2,3,4,5,6,7,8,9,10,11,12);
$break_after = array(5,2,5);
$counter = 0;
$break_key=0;
$totalNumber = count($data);
foreach ($data as $item){
if ($counter % $break_after[$break_key] == 0){
echo '<ul>';
}
echo '<li>'.$item.'</li>';
if ($counter % $break_after[$break_key] == ($break_after[$break_key]-1) || $counter == $totalNumber-1) {
echo '</ul>';
++$break_key;
$counter = 0;
}else{
++$counter;
}
}
Output for same is :
<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>
<ul><li>6</li><li>7</li></ul>
<ul><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li></ul>
To achieve what you want use the following:
<?php
$data = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22);
$total = count($data);
foreach ($data as $index => $item)
{
if ($index == 0 || $index == 5 || $index == 7 || ($index > 8 && ($index - 2) % 5 == 0))
{
echo '<ul>';
}
echo '<li>'.$item.'</li>';
if ($index == 4 || $index == 6 || $index == $total - 1 || ($index > 6 && ($index - 2) % 5 == 4)) {
echo '</ul>';
}
}
Pretty much the same answer as varunsinghal and Vivek Tankaria, but refactored to separate the logic and the view:
<?php
$pattern = [5, 2, 5, 5];
$data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
if (count($data) < array_sum($pattern)) {
throw new Exception('Please provide at least the same amount of data as lines required in the pattern');
}
?>
<?php foreach ($pattern as $limit): ?>
<ul>
<?php for ($i = 0; $i < $limit; $i++): ?>
<li><?= $data[$i]; ?></li>
<?php endfor; ?>
</ul>
<?php endforeach; ?>
For multiple values in array.
$data = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36);
$break_after = array(5,2,5);
$counter = 0;
$break_key=0;
$totalNumber = count($data);
foreach ($data as $item){
if ($counter % $break_after[$break_key] == 0){
echo '<ul>';
}
echo '<li>'.$item.'</li>';
if ($counter % $break_after[$break_key] == ($break_after[$break_key]-1)) {
echo '</ul>';
++$break_key;
if(count($break_after)==($break_key)){
$break_key=0;
}
$counter = 0;
}else{
++$counter;
}
}
?>
You can try this logic
<?php
$data = array(1,2,3,4,5,6,7,8,9,10,11,12);
$breakPoint=4;
$ct=1;
echo '<ul>';
foreach($data as $k=>$v){
echo '<li>'.$v.'</li>';
if($breakPoint == $k && $ct==1){
$breakPoint=$breakPoint+2;
$ct=2;
echo '</ul><br/><ul>';
}elseIf($breakPoint == $k && $ct==2){
$breakPoint=$breakPoint+5;
$ct=1;
echo '</ul><br/><ul>';
}
}
echo '</ul>';
?>
Output:
1
2
3
4
5
6
7
8
9
10
11
12
First break is at 5 so $i will be 4 then 2 elements more so $i will be 6. After this the break is required after every 5 elements, so we have 5+2+5 = 12 elements which gives $i=11 So similarly other break points will be 11 16 21 26 31 36 and so on.
<ul>
<?php
$i=0;
foreach($data as $item){
echo '<li>'.$item.'</li>';
if($i==4 || $i==6 || $i==11 || $i==16 || $i==21 || $i==26){
echo '</ul><ul>';
}
$i++;
}
?>
</ul>
I asked a similar question like this yesterday but after waiting for ever I figured out part of the problem but now I'm stuck again I'm trying to display ... when the search results are to long because my pagination links will keep on displaying and will not stop until every link is displayed on the page.
For example I'm trying to achieve the following in the example below. Can some one help me fix my code so I can update my site. Thanks
This is what I want to be able to do.
First Previous 1 2 ... 5 6 7 8 9 10 11 12 13 ... 199 200 Next Last
Here is my pagination code that displays the links.
$display = 20;
if (isset($_GET['p']) && is_numeric($_GET['p'])) {
$pages = $_GET['p'];
} else {
$q = "SELECT COUNT(id) FROM comments WHERE user_id=3";
$r = mysqli_query ($mysqli, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($mysqli));
$row = mysqli_fetch_array ($r, MYSQLI_NUM);
$records = $row[0];
if ($records > $display) {
$pages = ceil ($records/$display);
} else {
$pages = 1;
}
}
if (isset($_GET['s']) && is_numeric($_GET['s'])) {
$start = $_GET['s'];
} else {
$start = 0;
}
//content goes here
if ($pages > 1) {
echo '<br /><p>';
$current_page = ($start/$display) + 1;
if ($current_page != 1) {
echo 'First';
}
if ($current_page != 1) {
echo 'Previous ';
}
for ($i = 1; $i <= $pages; $i++) {
if ($i != $current_page) {
echo '' . $i . ' ';
} else {
echo '<span>' . $i . '</span> ';
}
}
if ($current_page != $pages) {
echo 'Next';
}
if ($current_page != $pages) {
echo 'Last';
}
echo '</p>';
}
Instead of the loop just use something like this:
if($current_page > 8 && $pages > 11) {
echo '1 ';
echo '2 ';
echo '...';
}
for ($i = max(1, $current_page - 4); $i < min($current_page + 4, $pages); $i ++) {
echo '' . $i . ' ';
}
if ($current_page < $pages - 8 && $pages > 11) {
echo '...';
echo '' . ($pages - 1) . ' ';
echo '' . $pages . ' ';
}