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
3 changes: 2 additions & 1 deletion .wp-env.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"plugins": [
"."
]
],
"testsEnvironment": false
}
66 changes: 63 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,44 @@ add_filter( 'blockparty_post_sharing_breakpoint', function () {
- **Parameters:** `int` — Breakpoint width in pixels.
- **Default:** `600`

### Icon customization
### Share networks (fallback menu)

Default icons are exposed as CSS custom properties on `.wp-block-blockparty-post-sharing-button`:
When the Web Share API is unavailable, the Share button opens a menu of social networks. Themes and plugins can customize the list with:

```php
add_filter( 'blockparty_post_sharing_networks', function ( $networks, $url, $title, $post_id ) {
// Remove WhatsApp.
$networks = array_values(
array_filter(
$networks,
static function ( $network ) {
return ( $network['id'] ?? '' ) !== 'whatsapp';
}
)
);

// Add Mastodon.
$networks[] = [
'id' => 'mastodon',
'label' => 'Mastodon',
'url' => 'https://mastodon.social/share?text=' . rawurlencode( $title . ' ' . $url ),
];

return $networks;
}, 10, 4 );
```

- **Filter name:** `blockparty_post_sharing_networks`
- **Parameters:**
- `array $networks` — List of networks (`id`, `label`, `url`)
- `string $url` — Post permalink
- `string $title` — Post title
- `int $post_id` — Post ID
- **Default:** Facebook, X, Bluesky, LinkedIn, WhatsApp

### Icon and menu customization

Default icons and the share fallback menu are exposed as CSS custom properties on `.wp-block-blockparty-post-sharing-button`:

```css
.wp-block-blockparty-post-sharing-button {
Expand All @@ -101,6 +136,30 @@ Default icons are exposed as CSS custom properties on `.wp-block-blockparty-post
--wp-block-blockparty-post-sharing-button-check-icon: url( '/path/to/check.svg' );
--wp-block-blockparty-post-sharing-button-icon-size: 1.25rem;
--wp-block-blockparty-post-sharing-button-icon-color: currentColor;

/* Share fallback menu */
--wp-block-blockparty-post-sharing-button-menu-offset: 0.5rem;
--wp-block-blockparty-post-sharing-button-menu-min-width: 12rem;
--wp-block-blockparty-post-sharing-button-menu-padding: 0.5rem;
--wp-block-blockparty-post-sharing-button-menu-gap: 0.25rem;
--wp-block-blockparty-post-sharing-button-menu-border-width: 1px;
--wp-block-blockparty-post-sharing-button-menu-border-style: solid;
--wp-block-blockparty-post-sharing-button-menu-border-color: currentColor;
--wp-block-blockparty-post-sharing-button-menu-border-radius: 0.25rem;
--wp-block-blockparty-post-sharing-button-menu-bg: #fff;
--wp-block-blockparty-post-sharing-button-menu-color: currentColor;
--wp-block-blockparty-post-sharing-button-menu-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.12);
--wp-block-blockparty-post-sharing-button-menu-link-padding: 0.5rem 0.75rem;
--wp-block-blockparty-post-sharing-button-menu-link-border-radius: 0.125rem;
--wp-block-blockparty-post-sharing-button-menu-link-hover-bg: rgba(0, 0, 0, 0.06);
--wp-block-blockparty-post-sharing-button-menu-link-gap: 0.5rem;
--wp-block-blockparty-post-sharing-button-menu-icon-size: 1.25rem;
--wp-block-blockparty-post-sharing-button-menu-icon-color: currentColor;
--wp-block-blockparty-post-sharing-button-menu-facebook-icon: url( '/path/to/facebook.svg' );
--wp-block-blockparty-post-sharing-button-menu-x-icon: url( '/path/to/x.svg' );
--wp-block-blockparty-post-sharing-button-menu-bluesky-icon: url( '/path/to/bluesky.svg' );
--wp-block-blockparty-post-sharing-button-menu-linkedin-icon: url( '/path/to/linkedin.svg' );
--wp-block-blockparty-post-sharing-button-menu-whatsapp-icon: url( '/path/to/whatsapp.svg' );
}
```

Expand All @@ -121,7 +180,8 @@ blockparty-post-sharing/
│ └── style.scss # Frontend and editor styles
├── includes/ # PHP classes
│ ├── BlockRenderer.php # Dynamic block rendering
│ └── ResponsiveDisplay.php # Responsive visibility rules
│ ├── ResponsiveDisplay.php # Responsive visibility rules
│ └── ShareNetworks.php # Share fallback networks (filterable)
├── build/ # Compiled assets (blocks-manifest.php, etc.)
├── languages/ # Translation files
├── .wordpress-org/blueprints/ # WordPress Playground blueprint
Expand Down
6 changes: 5 additions & 1 deletion blockparty-post-sharing.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@
}

if ( is_readable( __DIR__ . '/vendor/autoload.php' ) ) {
include_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/vendor/autoload.php';
} else {
require_once __DIR__ . '/includes/BlockRenderer.php';
require_once __DIR__ . '/includes/ResponsiveDisplay.php';
require_once __DIR__ . '/includes/ShareNetworks.php';
}

define( 'BLOCKPARTY_POST_SHARING_VERSION', '1.0.0' );
Expand Down
3 changes: 3 additions & 0 deletions includes/BlockRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ public static function render( $attributes ) {
'data-url' => esc_url( $url ),
'data-title' => esc_attr( $title ),
'data-copied-label' => esc_attr( $copied_label ),
'data-networks' => wp_json_encode(
ShareNetworks::get_networks( $url, $title, (int) $post_id )
),
];

if ( ! empty( $wrapper_classes ) ) {
Expand Down
107 changes: 107 additions & 0 deletions includes/ShareNetworks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

namespace Blockparty\PostSharing;

class ShareNetworks {

/**
* Get social networks for the share fallback menu.
*
* @param string $url Post permalink.
* @param string $title Post title.
* @param int $post_id Post ID.
*
* @return array<int, array{id: string, label: string, url: string}>
*/
public static function get_networks( string $url, string $title = '', int $post_id = 0 ): array {
$encoded_url = rawurlencode( $url );
$encoded_title = rawurlencode( $title );
$encoded_text = rawurlencode( '' !== $title ? $title . ' ' . $url : $url );

$networks = [
[
'id' => 'facebook',
'label' => 'Facebook',
'url' => 'https://www.facebook.com/sharer/sharer.php?u=' . $encoded_url,
],
[
'id' => 'x',
'label' => 'X',
'url' => 'https://x.com/intent/post?url=' . $encoded_url . '&text=' . $encoded_title,
],
[
'id' => 'bluesky',
'label' => 'Bluesky',
'url' => 'https://bsky.app/intent/compose?text=' . $encoded_text,
],
[
'id' => 'linkedin',
'label' => 'LinkedIn',
'url' => 'https://www.linkedin.com/sharing/share-offsite/?url=' . $encoded_url,
],
[
'id' => 'whatsapp',
'label' => 'WhatsApp',
'url' => 'https://api.whatsapp.com/send?text=' . $encoded_text,
],
];

/**
* Filter social networks used in the share fallback menu.
*
* Each network should provide:
* - id (string): Network slug used as a CSS modifier.
* - label (string): Visible network name.
* - url (string): Absolute share URL for the current post.
*
* @param array $networks Social network definitions.
* @param string $url Post permalink.
* @param string $title Post title.
* @param int $post_id Post ID.
*/
$networks = apply_filters(
'blockparty_post_sharing_networks',
$networks,
$url,
$title,
$post_id
);

if ( ! is_array( $networks ) ) {
return [];
}

return array_values(
array_filter(
array_map( [ self::class, 'sanitize_network' ], $networks )
)
);
}

/**
* Sanitize a single network definition.
*
* @param mixed $network Network definition.
*
* @return array{id: string, label: string, url: string}|null
*/
private static function sanitize_network( $network ): ?array {
if ( ! is_array( $network ) ) {
return null;
}

$id = isset( $network['id'] ) ? sanitize_key( (string) $network['id'] ) : '';
$label = isset( $network['label'] ) ? sanitize_text_field( (string) $network['label'] ) : '';
$url = isset( $network['url'] ) ? esc_url_raw( (string) $network['url'] ) : '';

if ( '' === $id || '' === $label || '' === $url ) {
return null;
}

return [
'id' => $id,
'label' => $label,
'url' => $url,
];
}
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"make-pot": "wp i18n make-pot . languages/blockparty-post-sharing.pot --exclude=\"src\" --domain=blockparty-post-sharing",
"make-json": "wp i18n make-json languages/blockparty-post-sharing-fr_FR.po languages/ --no-purge",
"start": "wp-scripts start --blocks-manifest",
"start:env": "wp-env start",
"stop:env": "wp-env stop"
"env:start": "wp-env start",
"env:stop": "wp-env stop"
},
"dependencies": {
"@wordpress/block-editor": "latest",
Expand Down
7 changes: 2 additions & 5 deletions src/blockparty-post-sharing/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@
}

&.is-display-preview-desktop.hide-copy-on-desktop &__copy,
&.is-display-preview-desktop.hide-share-on-desktop &__share {
display: none;
}

&.is-display-preview-desktop.hide-share-on-desktop &__share,
&.is-display-preview-mobile.hide-copy-on-mobile &__copy,
&.is-display-preview-mobile.hide-share-on-mobile &__share {
display: none;
opacity: .5;
}
}
3 changes: 3 additions & 0 deletions src/blockparty-post-sharing/img/bluesky.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/blockparty-post-sharing/img/facebook.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/blockparty-post-sharing/img/linkedin.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/blockparty-post-sharing/img/whatsapp.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/blockparty-post-sharing/img/x.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading