我们对模糊NSFW内容的解决方案

在 Blender Artists 论坛,我们实行相对宽松的内容政策,允许展示裸露和暴力内容(在一定限度内)。虽然大多数成员可以接受这类内容,但当然也存在不适合展示这些内容的受众和场合(对我们来说主要是学校和儿童)。由于我们大量使用带有 Topic List Preview 插件 的分块图库,因此我们需要一种方法,使这类内容默认对用户隐藏,并让用户选择是否查看。

解决方案的实施比预期的要简单,我决定在此分享,以防其他人也能从中受益。事先声明:我会在此链接一些不适合工作场所(NSFW)的内容。让我们开始吧!

我们早已要求所有相关帖子必须添加 #nsfw 标签,并在过去几个月里严格执行。我们的 AdSense 插件已配置为不在这些页面上显示广告,因为那样会(而且已经)让我们陷入与谷歌的麻烦中。(特别感谢 @neil 添加此功能!)

通过使用一些 CSS,我们为这些主题内的所有媒体添加了模糊效果和覆盖文字。鼠标悬停时模糊效果会被移除:

/* 在 #nsfw 主题中的任何媒体上显示 NSFW 模糊和覆盖文字 */
.tag-nsfw { 
	.topic-body .cooked img, 
	.topic-body .cooked iframe, 
	.topic-body .cooked .lazyYT-container, 
	.topic-thumbnail img {
        filter: blur(10px);	
        -webkit-transition: .3s ease-in-out;
        transition: .2s ease-in-out;
	}

	.topic-body:hover .cooked img, 
	.topic-body:hover .cooked iframe,
	.topic-body:hover .cooked .lazyYT-container, 			
	.topic-thumbnail:hover img {
        filter: blur(0);	
        -webkit-transition: .3s ease-in-out;
        transition: .2s ease-in-out;
	}

	.topic-body .cooked a.lightbox:before, 
	.topic-body .cooked iframe:before,
	.topic-thumbnail a:before {
	    z-index:2;
        padding: 5px;
        font-size:1em;
        position:absolute;

        color:#fff;
        content: '⚠️ 成熟内容 - 悬停显示';
        background: #e86800;

	}
	
	.topic-body .cooked a.lightbox:before, 
	.topic-body .cooked iframe:before {
        top: 15px;
        left: 10px;
	}

	.topic-thumbnail a:before {
        top: 65px;
        left: 20px;
	}
	
	.topic-body .cooked a.lightbox:hover:before, 
	.topic-body .cooked iframe:hover:before,
	.topic-thumbnail a:hover:before {		
	    display:none;
	}
}

主题中的图片和视频现在看起来是这样的:

而在任何 TLP 分块图库中,我们显示如下:

接下来,我们添加了一个首选项,允许用户禁用其账户的模糊效果。通过使用自定义字段,这比我们想象的要容易实现。

我们首先创建了一个复选框自定义字段:

然后,我们重用了部分代码,为这些用户向 body 类添加了 ‘nsfw-always-show’ 标签:

<!-- 将当前用户的 NSFW 偏好添加到 body 标签 -->
<script type="text/discourse-plugin" version="0.8">

// https://meta.discourse.org/t/css-classes-for-group-membership-for-simplified-ui-mode/60838/2
if (window.jQuery) {
    window.jQuery(function ($) {
        var u = Discourse.User.current();

        // 始终显示 NSFW
        if (u.custom_fields.user_field_2) {
            console.log('为当前用户显示 NSFW');
            $('body').addClass('nsfw-always-show' );
        }

    });
};

</script>

最后一段 CSS 代码会移除这些用户的模糊效果:

/* 在注册表单中隐藏自定义字段 */

.login-form .user-fields {display:none;}

/* 为在首选项中设置此选项的用户禁用 NSFW 模糊 */

.nsfw-always-show .tag-nsfw {
	.topic-body .cooked img, 
	.topic-body .cooked iframe, 
	.topic-body .cooked .lazyYT-container, 
	.topic-thumbnail img {
        filter: blur(0px);	
	}
	
	.topic-body .cooked a.lightbox:before, 
	.topic-body .cooked iframe:before,
	.topic-thumbnail a:before {
	    display:none;
	    content: none;
	}
}

这种方法的已知问题是,由于不支持 :hover,目前在移动设备上效果不佳。

如果您想查看实际效果,可以访问我们的 #nsfw 标签页面,但请注意,您可能会在那里看到一些 NSFW 内容 :slight_smile:

希望这对某人有帮助!

55 个赞

Also, on desktop, if an image take some space on the screen, you can easily hover it by mistake.
Instead of hovering to unblur, what about dynamically add a button “show the nsfw image” on top or under each nsfw image ?

4 个赞

krita-artists.org 上,我们将其稍作修改,改为点击触发而非悬停触发。但个人资料中使用的设置无法生效。即使用户已设置为显示 NSFW 内容,他看到的仍是模糊的内容。对此有解决办法吗?

我无法再编辑我的原帖了,但这里是更新后的代码。你愿意分享一下你的“点击”解决方案吗?

<!-- 将当前用户的 NSFW 偏好添加到 body 标签 -->
<script type="text/discourse-plugin" version="0.8.7">

// https://meta.discourse.org/t/css-classes-for-group-membership-for-simplified-ui-mode/60838/2
if (window.jQuery) {
    window.jQuery(function ($) {

        let currentUser = api.getCurrentUser();
        
        if (currentUser) {
            api.container.lookup('store:main').find('user', currentUser.username).then((user) => {

                if (user.user_fields[2]) {
                    $('body').addClass('nsfw-always-show' );
                }
            });
        }
    });
};
</script>
2 个赞

我们的 onlick 解决方案有些权宜之计,我认为可能并非最佳方案。我们只是移除了悬停时的模糊效果,并默认添加了模糊。消息也改为提示用户需要点击才能进入帖子。现在,用户必须点击才能进入帖子,再点击才能在灯箱中显示 NSFW 图片。这虽然繁琐,但能防止因误悬停而意外显示内容。或许可以使用 JavaScript 在点击时移除模糊效果。

/* 在 #nsfw 主题中为任何媒体显示 NSFW 模糊和覆盖文本 */
.tag-nsfw { 
.topic-thumbnail {
    overflow:hidden;
}

	.topic-body .cooked .lightbox img, 
	.topic-body .cooked iframe, 
	.topic-body .cooked .lazyYT-container, 
	.topic-thumbnail img {
    filter: blur(30px);	
    -webkit-transition: .3s ease-in-out;
    transition: .2s ease-in-out;
	}

	.topic-body .cooked a.lightbox:before, 
	.topic-body .cooked iframe:before,
	.topic-thumbnail a:before {
	    z-index:2;
    padding: 5px;
    font-size:1em;
    position:absolute;

    color:#fff;
    content: '⚠️ 成熟内容 - 点击查看图片';
    background: #000;

	}
	
	.topic-body .cooked a.lightbox:before, 
	.topic-body .cooked iframe:before {
    top: 50%;
    left: 10px;
    right: 10px;
    text-align:center;
	}

	.topic-thumbnail a:before {
    top: 65px;
    left: 20px;
	}
	
}

/* 隐藏注册表单中的自定义字段 */
.login-form .user-fields {display:none;}

/* 为在偏好设置中禁用 NSFW 模糊的用户关闭模糊效果 */
.nsfw-always-show .tag-nsfw {
	.topic-body .cooked img, 
	.topic-body .cooked iframe, 
	.topic-body .cooked .lazyYT-container, 
	.topic-thumbnail img {
    filter: blur(0px);	
	}
	
	.topic-body .cooked a.lightbox:before, 
	.topic-body .cooked iframe:before,
	.topic-thumbnail a:before {
	    display:none;
	    content: none;
	}
}

@bartv @Terrapop

如果有人愿意接手,可以利用 Discourse Image Filter 来构建一个“自动 NSFW 模糊”插件。

4 个赞

你好,请问我需要怎么做才能移除模糊效果,并将文本改为超链接,以便将其链接到我们希望的外部捐赠页面?

1 个赞

很抱歉,仅靠 CSS 无法实现这一点;您需要添加自己的代码来完成。

2 个赞

只需从 CSS 中删除 filter: blur(10px); 行。

5 个赞

@bartv 我已将首帖设为 wiki,如有需要请随时更新!:folded_hands:

10 个赞