Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion blockroll.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Plugin Name: Blogroll & Podroll Block
* Plugin URI: https://github.com/pfefferle/wordpress-blockroll
* Description: Share the blogs and podcasts you follow, and let other people subscribe to your list.
* Version: 2.0.0
* Version: 2.1.0
* Requires at least: 6.8
* Requires PHP: 7.4
* Author: Matthias Pfefferle
Expand Down
35 changes: 29 additions & 6 deletions build/blogroll/render.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 8 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
- Tags: blogroll, podroll, opml, links, feeds
- Requires at least: 6.8
- Tested up to: 7.1
- Stable tag: 2.0.0
- Stable tag: 2.1.0
- Requires PHP: 7.4
- License: GPL-2.0-or-later
- License URI: https://www.gnu.org/licenses/gpl-2.0.html
Expand Down Expand Up @@ -45,8 +45,9 @@ you have met. It shows up as a small note under the entry, and it is readable fo
that map who knows whom.

**Sorting and paging for visitors.** Long lists get pages, and visitors can sort by name
or by what you added last. There is no JavaScript in the list at all, every click is a
normal page load, and you can switch the sorting off per block.
or by what you added last. On a page with several lists, sorting or paging one leaves the
others as they are. There is no JavaScript in the list at all, every click is a normal
page load, and you can switch the sorting off per block.

## Frequently Asked Questions

Expand Down Expand Up @@ -132,6 +133,10 @@ routes are described in the

Project and support maintained on github at [pfefferle/wordpress-blockroll](https://github.com/pfefferle/wordpress-blockroll).

### 2.1.0

* Sorting and paging mean one list now. On a page with several blogrolls, sorting one no longer sorts the others, and paging one no longer pages them. The links say which list they mean, with the name every list has anyway: `?blockroll-sort=name&group=podcasts`. Links from before this version still sort and page every list on the page. Reported in #2.

### 2.0.0

* Every link is a block of its own now. You can move it, duplicate it, copy it to another page, and edit it where it shows: the name and the description in the list, the address behind the name, the feed and the relationships in the line below, the image by clicking it.
Expand Down
35 changes: 29 additions & 6 deletions src/blogroll/render.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/

use Blockroll\Links;
use Blockroll\Opml;
use Blockroll\Sources;
use Blockroll\Xfn;

Expand All @@ -22,12 +23,18 @@
$blockroll_sortable = $attributes['showSort'];

// The HTML anchor is the address of this one list. The sorting and paging
// links carry it, so the reload lands on the list that was clicked, not
// at the top of the page.
// links carry it twice: as the fragment, so the reload lands on the list
// that was clicked, and as the group, the same query var the subscription
// files use, so that sorting and paging mean this list alone. A query
// that names no list means every list, the way the links of the versions
// before this one did.
$blockroll_anchor = trim( (string) ( $attributes['anchor'] ?? '' ) );
$blockroll_fragment = '' !== $blockroll_anchor ? '#' . $blockroll_anchor : '';
$blockroll_named = trim( (string) get_query_var( Opml::GROUP ) );
$blockroll_meant = '' === $blockroll_named || $blockroll_named === $blockroll_anchor;
$blockroll_group = '' !== $blockroll_anchor ? $blockroll_anchor : false;

$blockroll_sort = $blockroll_sortable ? get_query_var( 'blockroll-sort' ) : '';
$blockroll_sort = $blockroll_sortable && $blockroll_meant ? get_query_var( 'blockroll-sort' ) : '';
if ( ! in_array( $blockroll_sort, array( 'name', 'added', 'manual' ), true ) ) {
$blockroll_sort = $attributes['sortBy'];
}
Expand All @@ -37,7 +44,7 @@
$blockroll_per = (int) $attributes['perPage'];
$blockroll_total = count( $blockroll_links );
$blockroll_pages = $blockroll_per > 0 ? max( 1, (int) ceil( $blockroll_total / $blockroll_per ) ) : 1;
$blockroll_page = min( max( 1, (int) get_query_var( 'blockroll-page', 1 ) ), $blockroll_pages );
$blockroll_page = $blockroll_meant ? min( max( 1, (int) get_query_var( 'blockroll-page', 1 ) ), $blockroll_pages ) : 1;
$blockroll_dated = (bool) array_filter( wp_list_pluck( $blockroll_links, 'added' ) );

if ( ! $blockroll_links ) {
Expand All @@ -48,6 +55,21 @@
$blockroll_links = array_slice( $blockroll_links, ( $blockroll_page - 1 ) * $blockroll_per, $blockroll_per );
}

/**
* The address of another page of this list.
*
* @param int $page Page number.
* @return string URL.
*/
$blockroll_page_url = function ( $page ) use ( $blockroll_group, $blockroll_fragment ) {
return add_query_arg(
array(
'blockroll-page' => $page,
Opml::GROUP => $blockroll_group,
)
) . $blockroll_fragment;
};

$blockroll_sorts = array(
'name' => __( 'By name', 'blockroll' ),
);
Expand All @@ -70,6 +92,7 @@
array(
'blockroll-sort' => $blockroll_key,
'blockroll-page' => false,
Opml::GROUP => $blockroll_group,
)
) . $blockroll_fragment;
?>
Expand Down Expand Up @@ -123,7 +146,7 @@
<?php if ( $blockroll_pages > 1 ) : ?>
<nav class="blockroll-pager">
<?php if ( $blockroll_page > 1 ) : ?>
<a href="<?php echo esc_url( add_query_arg( 'blockroll-page', $blockroll_page - 1 ) . $blockroll_fragment ); ?>"><?php esc_html_e( 'Previous', 'blockroll' ); ?></a>
<a href="<?php echo esc_url( $blockroll_page_url( $blockroll_page - 1 ) ); ?>"><?php esc_html_e( 'Previous', 'blockroll' ); ?></a>
<?php endif; ?>
<span>
<?php
Expand All @@ -132,7 +155,7 @@
?>
</span>
<?php if ( $blockroll_page < $blockroll_pages ) : ?>
<a href="<?php echo esc_url( add_query_arg( 'blockroll-page', $blockroll_page + 1 ) . $blockroll_fragment ); ?>"><?php esc_html_e( 'Next', 'blockroll' ); ?></a>
<a href="<?php echo esc_url( $blockroll_page_url( $blockroll_page + 1 ) ); ?>"><?php esc_html_e( 'Next', 'blockroll' ); ?></a>
<?php endif; ?>
</nav>
<?php endif; ?>
Expand Down
102 changes: 102 additions & 0 deletions tests/test-render.php
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,108 @@ public function test_wrapper_carries_style_supports() {
$this->assertStringContainsString( 'line-height:1.8', $html );
}

/**
* Two lists on a page share the query, so the sorting and the paging
* say which list they mean: the anchor, in the same query var the
* subscription files use.
*/
public function test_sort_applies_to_the_named_list_only() {
$attrs = array(
'anchor' => 'podcasts',
'sortBy' => 'manual',
'links' => array(
array(
'url' => 'https://b.example/',
'name' => 'Beta',
),
array(
'url' => 'https://a.example/',
'name' => 'alpha',
),
),
);

set_query_var( 'blockroll-sort', 'name' );

set_query_var( 'group', 'podcasts' );
$html = $this->render_block_html( $attrs );
$this->assertLessThan( strpos( $html, 'Beta' ), strpos( $html, 'alpha' ), 'the named list is sorted' );

set_query_var( 'group', 'blogs' );
$html = $this->render_block_html( $attrs );
$this->assertLessThan( strpos( $html, 'alpha' ), strpos( $html, 'Beta' ), 'another list keeps its own order' );

// Links from before the lists had names still sort every list.
set_query_var( 'group', null );
$html = $this->render_block_html( $attrs );
$this->assertLessThan( strpos( $html, 'Beta' ), strpos( $html, 'alpha' ) );

set_query_var( 'blockroll-sort', null );
}

public function test_sort_links_name_their_list() {
$html = $this->render_block_html(
array(
'anchor' => 'podcasts',
'links' => self::TWO_DATED_LINKS,
)
);

$this->assertStringContainsString( 'group=podcasts', $html );
$this->assertStringContainsString( '#podcasts', $html );
}

public function test_paging_applies_to_the_named_list_only() {
$attrs = array(
'anchor' => 'podcasts',
'perPage' => 1,
'links' => array(
array(
'url' => 'https://a.example/',
'name' => 'A',
),
array(
'url' => 'https://b.example/',
'name' => 'B',
),
),
);

set_query_var( 'blockroll-page', 2 );

set_query_var( 'group', 'podcasts' );
$html = $this->render_block_html( $attrs );
$this->assertStringContainsString( 'b.example', $html );

set_query_var( 'group', 'blogs' );
$html = $this->render_block_html( $attrs );
$this->assertStringContainsString( 'a.example', $html, 'another list stays on its first page' );

set_query_var( 'blockroll-page', null );
set_query_var( 'group', null );
}

public function test_paging_links_name_their_list() {
$html = $this->render_block_html(
array(
'anchor' => 'podcasts',
'perPage' => 1,
'links' => array(
array(
'url' => 'https://a.example/',
'name' => 'A',
),
array(
'url' => 'https://b.example/',
'name' => 'B',
),
),
)
);

$this->assertStringContainsString( 'group=podcasts', $html );
}

/**
* A list that is not in the file of its page still offers its own, so
* the download link points at the file of the list.
Expand Down
Loading