WordPress 新主题 Weisay Grace
新年新气象,感谢大发 hera 主题的一年陪伴,想着换一个,发现了威言威语发布了新主题 Weisay Grac […]
新年新气象,感谢大发 hera 主题的一年陪伴,想着换一个,发现了威言威语发布了新主题 Weisay Grac […]
这款插件是我找deepseek写的,主要功能是把typecho发布的内容自动同步到Memos上。应该是绝大部分博主都用不上,各取所需吧!也是想说,AI成熟了,我们每位都是程序员,都可以让AI写出自己想要的功能的代码!
一直以来,除老张博客外,还有一个后花园,老张随笔。老张随笔就是每天记一些点滴,发一点牢骚!字数都是在一两百字,到目前为止,也记录了近一千五百篇日志了。老张随笔最初选用的是较轻量的Typecho程序,后来Memos在博客圈流行的时候,老张随笔便换成了Memos程序,这样能更好的和五木大佬开发的哔哔广场融合。Typecho数据导入到Memos数据库中也非常的简单,这篇《简单几步,Typecho博客文章轻松导入到Memos》教程,便可以教大家很方便的把Typecho的文章导入到Memos中。Memos也使用了两三年吧,但是由于作者的任性更新,版本一直还停留在0.18.1上。加之大家对Memos热度的减少,现在玩Memos的人很少了,原来五木大佬的哔哔广场,每天都好几十条哔文,现在基本上很少有人发了。种种原因,老张随笔又换回了Typecho程序,但是老张又舍不得Memos,所以在Typecho上发布一篇文章后,便手动复制到Memos上,也算是做为备份吧!每天手动甚是麻烦,便有了这款Typecho插件-MemosSync,Memos同步插件。
✅ 文章发布时自动同步到Memos
✅ 支持将文章分类作为Memos标签
✅ 可配置可见性(公开/受保护/私有)
✅ 完整的错误处理,不影响文章发布
✅ 后台配置界面
1.安装插件
将下面的文件上传到 /usr/plugins/MemosSync/ 目录
在Typecho后台启用插件
2.配置插件:
进入插件设置页面
填写Memos地址(例如:https://memos.example.com)
输入Access Token(在Memos设置中生成)
选择可见性设置
启用同步功能
3.获取Access Token:
登录您的Memos实例
进入设置 → 权限 → Access Tokens
生成新的Token并复制到插件设置中
确保您的Typecho服务器可以访问Memos实例
如果同步失败,会在Typecho日志中记录错误信息
标签会自动过滤特殊字符,只保留字母、数字、中文和下划线
/usr/plugins/MemosSync/
├── Plugin.php ├── config.xml └── form.php
1. config.xml
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<name>MemosSync</name>
<description>将Typecho文章同步到Memos</description>
<author>Your Name</author>
<version>1.0.0</version>
<module>MemosSync</module>
</plugin>
2. form.php
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<h2>Memos 同步设置</h2>
<div class="typecho-page-title">
<h2>Memos 配置</h2>
</div>
<div class="typecho-option">
<label class="typecho-label" for="memos_url">Memos 地址</label>
<input type="text" class="text" name="memos_url" id="memos_url" value="<?php $this->options->memos_url(); ?>" />
<p class="description">请输入完整的Memos地址,例如:https://memos.example.com</p>
</div>
<div class="typecho-option">
<label class="typecho-label" for="memos_token">Access Token</label>
<input type="text" class="text" name="memos_token" id="memos_token" value="<?php $this->options->memos_token(); ?>" />
<p class="description">在Memos设置中生成的Access Token</p>
</div>
<div class="typecho-option">
<label class="typecho-label" for="memos_visibility">可见性</label>
<select name="memos_visibility" id="memos_visibility">
<option value="PUBLIC" <?php if($this->options->memos_visibility == 'PUBLIC') echo 'selected'; ?>>公开</option>
<option value="PROTECTED" <?php if($this->options->memos_visibility == 'PROTECTED') echo 'selected'; ?>>受保护</option>
<option value="PRIVATE" <?php if($this->options->memos_visibility == 'PRIVATE') echo 'selected'; ?>>私有</option>
</select>
<p class="description">选择同步到Memos的可见性设置</p>
</div>
<div class="typecho-option">
<label class="typecho-label">
<input type="checkbox" name="memos_enable_sync" value="1" <?php if($this->options->memos_enable_sync == '1') echo 'checked'; ?> />
启用同步功能
</label>
<p class="description">启用后,发布文章时会自动同步到Memos</p>
</div>
<div class="typecho-option">
<label class="typecho-label">
<input type="checkbox" name="memos_include_tags" value="1" <?php if($this->options->memos_include_tags == '1') echo 'checked'; ?> />
包含分类作为标签
</label>
<p class="description">将文章分类作为Memos的标签</p>
</div>
3. Plugin.php
<?php
/**
* MemosSync - Typecho文章同步到Memos插件
*
* @package MemosSync
* @author Your Name
* @version 1.0.0
* @link https://yourblog.com
*/
class MemosSync_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件
*/
public static function activate()
{
Typecho_Plugin::factory('Widget_Contents_Post_Edit')->finishPublish = array('MemosSync_Plugin', 'syncToMemos');
Typecho_Plugin::factory('Widget_Contents_Post_Edit')->finishSave = array('MemosSync_Plugin', 'syncToMemos');
return _t('插件已激活,请配置Memos设置');
}
/**
* 禁用插件
*/
public static function deactivate()
{
return _t('插件已禁用');
}
/**
* 插件配置面板
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
require_once 'form.php';
}
/**
* 个人用户的配置面板
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form) {}
/**
* 同步到Memos
*/
public static function syncToMemos($contents, $post)
{
// 获取插件配置
$options = Typecho_Widget::widget('Widget_Options');
$memosUrl = $options->plugin('MemosSync')->memos_url;
$memosToken = $options->plugin('MemosSync')->memos_token;
$memosVisibility = $options->plugin('MemosSync')->memos_visibility;
$enableSync = $options->plugin('MemosSync')->memos_enable_sync;
$includeTags = $options->plugin('MemosSync')->memos_include_tags;
// 检查是否启用同步
if (!$enableSync) {
return;
}
// 验证必要配置
if (empty($memosUrl) || empty($memosToken)) {
return;
}
try {
// 准备请求数据
$apiUrl = rtrim($memosUrl, '/') . '/api/v1/memos';
$content = $contents['text'];
// 如果启用了标签功能,获取分类作为标签
$tags = array();
if ($includeTags && isset($contents['category'])) {
$category = $contents['category'];
if (is_array($category)) {
$tags = $category;
} else {
$tags = array($category);
}
}
// 构建内容,包含标签
$memoContent = $content;
if (!empty($tags)) {
$tagString = '';
foreach ($tags as $tag) {
$tagString .= ' #' . self::formatTag($tag);
}
$memoContent .= "\n\n" . $tagString;
}
// 准备请求数据
$postData = array(
'content' => $memoContent,
'visibility' => $memosVisibility
);
// 发送请求到Memos
$http = Typecho_Http_Client::get();
if ($http) {
$http->setHeader('Authorization', 'Bearer ' . $memosToken)
->setHeader('Content-Type', 'application/json')
->setData(json_encode($postData))
->setTimeout(30)
->send($apiUrl);
$response = $http->getResponseBody();
$status = $http->getResponseStatus();
if ($status != 200) {
throw new Exception('Memos API 返回错误: ' . $status . ' - ' . $response);
}
}
} catch (Exception $e) {
// 记录错误日志,但不影响文章发布
Typecho_Log::write('MemosSync Error: ' . $e->getMessage(), Typecho_Log::WARN);
}
}
/**
* 格式化标签
*/
private static function formatTag($tag)
{
// 移除特殊字符,只保留字母、数字、中文、下划线
$tag = preg_replace('/[^\p{L}\p{N}_]/u', '', $tag);
return $tag;
}
}
WordPress 如何让 RSS feed 输出全文? WordPress RSS 设置全文输出教程 教你让 WordPress 的 RSS 订阅显示全文 WordPress:让 RSS 订阅源输出完整内容的三种方法 修改 WordPress /feed 输出全文的完整指南 RSS 只显示摘要?教你改成全文(WordPress 设置/代码/插件) WordPress RSS 全文输出配置:设置、代码与插件方案 如何强制 WordPress RSS 显示完整内容(含 functions.php 方法) 提升订阅体验:WordPress RSS 输出全文的解决方案 WordPress RSS 订阅优化:开启全文输出的最佳实践在 WordPress 中,/feed(RSS 订阅源)是输出完整内容还是仅输出摘要,可以在 管理后台 → 设置 → 阅读 中控制,也可以通过代码或插件自定义。下面是逐步指南:
functions.php 文件。
// 强制 RSS 订阅源显示完整内容
function my_full_feed_content($content) {
return get_the_content();
}
add_filter('the_excerpt_rss', 'my_full_feed_content');
add_filter('the_content_feed', 'my_full_feed_content');
这可确保 RSS 摘要和内容订阅源都使用完整文章内容。
/feed 或 /feed/rss2/ 测试你的订阅源以确认输出为全文。一些缓存插件可能需要清除缓存。
附注:本博客的订阅源已切换为输出全文。
[show_file file="/var/www/wp-post-common/justyy.com/wordpress.php"]
英文:Wordpress: How to Output Full Text in the Feed?最终效果见这里。
我这个人既不喜欢旅游,也不喜欢摄影,没出过国也没在国内溜达过几个地方,但这并不妨碍我也有一颗上线足迹地图的心。无奈谷歌地图连不上,百度地图不想连,OSM(OpenStreetMap)既连不上也连不明白,就搁置了。
直到上周,@Dayu上线了他的地图插件,试用之后发现表现形式与期待值有差距,想在帖子下面留言发建议的时候,发现了明明同学的另一份方案。虽然主要是js实现的,只需要知道leaflet这个开源库的名字,我就知道以Wordpress的海量扩展,这回成了!
找到了一个插件和插件的插件,配置之后,算是达到了心目中的效果。
插件使用比较复杂,这里记录一下,给自己个备忘,能帮到人更好。
插件地址:Leaflet Map。
逐一说明一下后台的配置项:
Default Latitude:
地图默认纬度
Default Longitude:
地图默认经度
Default Zoom:
地图默认缩放比
Default Height:
默认高度
Default Width:
默认宽度
上面五个值可以以短代码参数的形式加到leaflet-map中,如果不加则使用后台的默认参。
Fit Bounds:
是否令地图随标记点的范围进行缩放。如果为true,那么地图会自动计算当前所有Marker的中心位置,以及包括所有Marker点的合适的缩放比。可以用默认值,也可以在map中单独设置。
Show Zoom Controls:
是否显示缩放按钮
Scroll Wheel Zoom:
是否允许滚轮缩放
这项设置之后,在地图上并不是直接用滚轮缩放,而是需要用Ctrl,感觉不便所以我自己没加。
Double Click Zoom:
是否允许双击放大
注意如果不显示缩放按钮的话,放大之后就回不来了。
Default Min/Max Zoom:
最小和最大放大倍数。最终的放大倍数不仅跟这个后台设定项有关,也跟使用的地图瓦片API有关。
Default Tiling Service:
有两个选项,“I will provide my own map tile URL”和MapQuest。MapQuest我考察了一番,感觉太难看,没继续尝试。所以重点说第一个选项,自定义tile URL。
先解释一下什么是tile URL。本插件所依赖的地图服务,叫做Map Tile Server(地图瓦片服务)。它分成Raster、Vector和Static三种形式。本插件使用的是Raster形式,而Dayu和明明同学用的都是Vector形式。Vector的参数更加丰富,Raster配置起来更简便。
※※※Map Tile URL※※※:
重中之重!!因为默认的OSM服务访问不了,所以这里必须填一个自定义的。
明明同学找的cartocdn就挺好用的。他使用的light_nolabels是不带标签的版本,换成light_all就是带标签的版本。至于他为什么用不带标签的,自己悟。
https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png
http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png
这里的{z}{x}{y}都不要动,第一个{s}是指地址里的subdomain,也就是接下来的配置项【Map Tile URL Subdomains】。
有的API是需要API Key的。这样的API都有说明文档,把Key按照人家给的例子粘贴进来即可。
cartocdn对我来说有点太素了,于是周末花了一天时间寻找能用的瓦片服务,结果惨不忍睹,汇报一下成果:
maptiler.com:要注册、被墙。
opentopomap.org:免注册、丑。
stadiamaps.com:要注册、比较流畅、免费用户限流严重
tomtom.com:要注册、慢、地图不详细
here.com:要注册、中文地名乱七八糟
geoapify.com:要注册、速度尚可、账号登录验证需要梯子,服务本身不需要。
至于为啥不找国内的地图服务,是我不想吗?本插件所支持的是Raster服务,也叫zxy服务,客户端GET的结果必须是一张PNG/JPG/WEBP图片。国产的高德和天地图我也试了,根本不是一样的格式。甚至有种说法,说国内不允许提供这种服务。
然后呢,这服务也可以自己搭建,数据和教程也都有,但总觉得这种行为像为了吃顿酱肘子先花一年时间晒酱油,没必要。
兜兜转转一圈,还是要回到cartocdn。什么功不唐捐,屁咧!
Map Tile URL Subdomains:
具体填什么要看API的文档说明,像openstreetmap和cartocdn都是abcde或a,b,c,d,e。有的API前面没有前缀那就不填。
Detect Retina:
是否检测高清设备。如果上面的瓦片服务中支持@2x,那么选中这项以后,如果leaflet发现使用者用的是高清屏幕,就会自动使用高清地图。窃以为意义不大。
Tile Size:
一般情况下服务本身已经设好了,留空即可。
Tile Id:
Access Token:
用Mapbox的服务才有用。但是我的Mapbox没配明白,只有一个默认的卫星地图能用,这两项也没用上。
Zoom Offset:
好像是在zoom的时候自动加减一下这个值,没理解意义。
No Wrap (tiles):
地图是否与经线对齐。(这有啥用?)
JavaScript URL、CSS URL:
css和js的位置,默认即可。
Default Attribution:
地图做成后,右下角的一串版权信息。尊重服务商要求即可。
再往后没用上。
插件装好后,其实已经可以编辑地图了。但因为还有个插件的插件,所以怎么用放后面再说。
插件地址:Extensions for Leaflet Map。
跟主插件正相反,这个插件的后台,大多数时间在说怎么用。
Marker Clustering–When you mouse over a cluster it shows the bounds of its markers.
聚合显示时,默认会将聚合的标记点连接起来形成一个多边形。我嫌不好看,勾掉了。
When you click a cluster we zoom to its bounds.
点击聚合点时,直接缩放到所有聚合点的范围。
语法和关键字很多,但能用上的不多。通常只需要地图、标记点、地形json文件。
leaflet-map:
主插件的主函数,用于插入一张leaflet-map。参数就是配置页面的那些,没什么特别的。
leaflet-marker:
标记一个地点。参数比较多,挑有用的说。
– lat,lng / address:用于定位标记的位置。lat是纬度,lng是经度。经纬度可以从OpenStreetMap.org上查。国产地图查到的经纬度与OSM查到的有一些偏差,注意要保持一致。而address的数据库偏差非常大,不建议。
– iconUrl:标记用图标。可以是网址,也可以是相对路径,甚至base64代码。如果不设,使用默认的蓝色pin图标。
– title:鼠标移动到标记点上时显示的提示信息。这个与点击标记后显示的内容是两码事。
– iconanchor:图标的锚点偏移。这个参数有点意思,它表示的是你图标的“尖”所在的位置。以默认图标为例,规格是19*25,“尖”在最下方,所以iconanchor就应该是宽的一半和全部的高,也就是10,25。这个参默认项是0,0。每个标记都要自己手动加,相当烦。不过也能够理解,一旦有人用的是左箭头呢?
– opacity:图标的透明度。
– 【leaflet-marker】【/leaflet-marker】之间,放置弹出的html内容。放啥都行,也可以定义css。
另外还有一些参数,我都没用上官网说明文档里都有。
leaflet-geojson:
地理信息的json文件。中国的地理信息文件可以在阿里云下载,或者直接引用。建议下载后到mapshaper进行优化后上传,在本地使用。这里非常感谢明明桑,一个优化工具解决了困扰我许久的问题。
– src:地理信息源文件的路径,可以是相对路径或网址。
– color:leaflet提供的属性,边框颜色。
– weight;leaflet提供的属性,边框宽度。
– opacity:leaflet提供的属性,边框透明度。默认的3px蓝色实在是有点虎。缺点是每个marker都需要单独设置。
– fill:leaflet提供的属性,布尔型,是否填充。默认true
– fillColor:leaflet提供的属性,填充颜色,不设则默认使用color
– fillOpacity:leaflet提供的属性,填充颜色的透明度,默认0.2
想一个省一个省点亮的,就下载省级json,想像我这样一个市一个市点亮的,就下载市级json,一次勾一个边即可。话说,我一直认为用省划分习俗非常不科学,甚至用市来划分都不科学。毕竟有粤南粤北、胶东鲁西南,还有江苏十三太保这样的众所周知的文化差异。我甚至觉得应该精确到县。毕竟我们旁边就有一个散装的地级市,我认识一堆人,他们分别来自鲅鱼圈、熊岳、盖州、老边、大石桥,就没有一个称自己是营口人的。但是真正实装以后才发现,县级太困难了,我甚至都没在普兰店歇过脚,自己家都没搞定。
markerclustergroup:聚合分组方法,这是“扩展的扩展”的功能,也是安装它的主要目地。cluster是指将临近的点进行聚合,group是通过关键字对追加的点进行分组。只聚合可以用cluster,只分组可以用leaflet-optiongroup。
– feat:适配项目。可以是【leaflet-marker】中的title或者iconUrl中的一个。参数以部分匹配的方式,对title或者iconUrl形成过滤,然后在右上角形成组别。
– strings:分组过滤用的字符串,用半角逗号间隔。
– groups:分组后显示的字符串。
– position :分组显示位置
– collapsed :分组是否折叠
【leaflet-map fitbounds】//用fitbounds,就不用关心点的位置和缩放了 【fullscreen】//增加一个全屏按钮 【leaflet-marker lat=38.87430121 lng=121.55204380 iconUrl="/path_to/marker-blue.png" iconanchor="15,40" 】<b>辽师附中</b><i>2012 /04 /<a href="/2012/04/ancient-school-motto.html" target="_blank" rel="noopener">沙河口黑石礁尖山街</a> /街拍 </i><img src="/path_to/imag0114.jpg" alt="imag0114" />【/leaflet-marker】 【leaflet-marker lat=38.88611421 lng=121.63731716 iconUrl="/path_to/marker-blue.png" iconanchor="15,40" opacity=0.5】<b>西岗中学</b><i>2003 /05 /<a href="/2023/06/post-truth-and-something-before-my-graduation.html" target="_blank" rel="noopener">西岗八一三环街</a> /其他 </i><img src="/path_to/vlcsnap-2023-05-21-17h15m27s675.jpg" alt="vlcsnap-2023-05-21-17h15m27s675" />【/leaflet-marker】 【leaflet-marker lat=38.88890 lng=121.70665 iconUrl="/path_to/marker-yellow.png" iconanchor="15,40" 】<b>棒棰岛</b><i>1993 /08 /中山老虎滩迎宾路 /海滩 </i>【/leaflet-marker】 【leaflet-marker lat=38.93471 lng=121.19765 iconUrl="/path_to/marker-yellow.png" iconanchor="15,40" 】<b>北海王家村</b><i>2018 /08 /旅顺北海王家村 /海滩 </i>【/leaflet-marker】 【leaflet-marker lat=38.98562089 lng=121.65895298 iconUrl="/path_to/marker-yellow.png" iconanchor="15,40" 】<b>蟹子湾</b><i>2015 /04 /<a href="/2015/04/chemical-factories-stories.html" target="_blank" rel="noopener">甘井子甘井子海茂路</a> /海滩 </i><img src="/path_to/BF59AEE251904BC4.jpg" alt="BF59AEE251904BC4" />【/leaflet-marker】 【markerclustergroup feat="iconUrl" strings="blue, yellow" groups="学校, 海滩" collapsed=true】 【leaflet-geojson src="/path_to/dalian.json" color="#FF8888" weight=2 fillOpacity=0.3】//加入大连地图 【zoomhomemap】//调整缩放比[fullscreen ] [markerclustergroup feat=iconUrl strings=blue, yellow groups=学校, 浴场 collapsed=true ] [zoomhomemap ]
就到这。总之有现成儿的我才不会亲自动手呢。
本文仅为插件使用帮助,插件更新内容请关注站内另一篇文章。
本轮更新已接近尾声,因为加了不少功能,干脆写一篇说明书。
卸载插件会删除数据库数据,如果有自定义数据建议备份后再删除。
新版插件不再使用post_meta 存储关键数据,建议有任何危险操作先行备份数据库,避免因数据无法恢复白白浪费时间导入数据。
首次安装必须使用
2.1.7及以上版本,否则无法正常创建数据表。
Map BOX token 是使用mapbox 的必须条件,可在https://www.mapbox.com,获取自己的token 来使用。每月有免费5万次的调用次数,一般来说都够用了。
最小缩放和最大缩放是限制地图zoom 比例的,如果marker 是全球的,建议设置为1,如果仅为国内设置为3比较合适,另外如果只定位到城市级别,建议最大设置为13以内。
中心坐标为初始化时地图的中心位置,如果开始自适应则会根据marker 自动居中,该设置无效。
检索距离则是相关文章的参数,会自动检索距离内的相关文章,单位时千米。
目前插件可以高亮去过的国家,没有细化国内省份。
2.0 版本之后本插件和Google Maps 深度绑定,数据互通,可相互导入导出,都是傻瓜操作,这里就不介绍了。
新版插件修改了逻辑,以前是以文章为基础,现在则是以marker 为基础,虽然文章页面提供了快捷入口,但还是建议在列表进行管理,可进行全字段管理,一些地名可能重复的原因搜索结果不准确,可增加更多关键词精准搜索结果,等数据正确后再修改名字即可。
地点里有一个类型,暂时默认为城市即可,此字段其实是为后续扩展使用,本轮更新并不会启用。
以下代码可显示当前文章绑定地点的国旗
<?php do_action('marker_pro_flag', get_the_ID()); ?>
插件已内置所有国家代码并自动匹配。
使用短代码
[marker id="7"]
在文章编辑页面直接提供了快捷方式,需使用经典tinymce 编辑器。
读取的是文章发布时间,也可以在marker 处自定义时间,支持多年设置。
方法和之前一样,不错现在支持传入参数进行设置,如果使用短代码则
[marker_pro filters=all,wish,done]
如果使用函数方式,则传参
marker_pro_init(filters='all,wish,done,plan')
仅支持all,wish,done,plan四种
因为后台可以初始状态,如果初始状态不在设置的类型中,则默认展示第一个。
插件提供了一个云端上传的选项,开启后相关文章不再从本地获取数据,可以拉到其他用户的文章,当然其他用户也会拉到你的文章。云端程序部署在cloudflare,不保证国内用户可以正常使用。
作为一款多年前的插件我推出之后就一直几乎没更新,最近有博友推出了开源版,鉴于本插件价格较为昂贵,本人直接做了个大版本更新,将体验感直接拉满。
为了提升使用体验,被迫做了破坏性更新,但提供了旧数据转换方法,可一键转换。
除了将官方SDK例行更新到最新版外,主要更新了以下内容
另外插件内置了一套国别系统,考虑到大部分人的旅行经历有限,本国别系统仅为尝试。
本插件的理念是深度绑定文章写作,而不是大而全的地图工具。
本次还对hugo 静态博客进行了支持,使用方法依然是只需要编辑文章markdown 文件,与插件设计理念保持一致。
目前还在细微调整阶段,最新版本自行下载即可。
五一假期结束啦!这五天啥也没干,就在宿舍敲代码,都快无聊死了,恰逢找到了一些免费API,就自己实现一个AI摘要吧!利用API生成摘要文本放在文章头部,再通过hexo进行渲染就好啦!