feat: 前台 paywall——整篇锁定渲染付费墙,付费块替换为 teaser
- membership/post.rendered 过滤:整篇锁定(members_only)渲染 paywall 视图(封面+标题+价格+单篇解锁/开通会员按钮,游客引导登录);[paid] 块替换为带解锁按钮的 teaser;替换改用 preg_replace_callback 避免 $ 转义问题 - 视图放 resources/views/membership/(主题同名文件可覆盖),两主题补充 .paywall/.paid-teaser 样式 - 修复泄漏:excerpt_or_fallback 对 members_only 文章不再回退截取正文,防止内容泄漏到 paywall 与 SEO meta - 测试:更新 teaser 断言,新增 guest 见 paywall、登录用户见解锁/会员按钮
This commit is contained in:
@@ -53,21 +53,21 @@ class ServiceProvider extends PluginServiceProvider
|
||||
}
|
||||
}, 10);
|
||||
|
||||
// 付费文章:[paid]...[/paid] 对无权限访客隐藏
|
||||
// 付费文章:[paid]...[/paid] 对无权限访客隐藏为 teaser;整篇锁定渲染 paywall
|
||||
$manager->addFilter('post.rendered', function (string $html, \App\Models\Post $post) {
|
||||
$service = app(Services\MembershipService::class);
|
||||
$user = auth()->user();
|
||||
|
||||
if (preg_match('/\[paid\](.*?)\[\/paid\]/s', $html) && ! $service->canReadPaidContent($user, $post)) {
|
||||
$html = preg_replace(
|
||||
$html = preg_replace_callback(
|
||||
'/\[paid\](.*?)\[\/paid\]/s',
|
||||
'<div class="paid-teaser">(付费内容已隐藏,开通会员或单篇解锁后可见)</div>',
|
||||
fn () => view('membership.paid-teaser', ['post' => $post])->render(),
|
||||
$html
|
||||
);
|
||||
}
|
||||
|
||||
if (! $service->canReadPost($user, $post)) {
|
||||
return '<div class="paid-teaser">(本文章为会员专享,开通会员后可见)</div>';
|
||||
return view('membership.paywall', ['post' => $post])->render();
|
||||
}
|
||||
|
||||
return $html;
|
||||
|
||||
Reference in New Issue
Block a user