本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/80767649
博主地址是:http://blog.csdn.net/freewebsys
前言
https://getqor.com/cn
QOR经过全新架构,以加速开发与部署内容管理系统(CMS)、电子商务系统和业务应用程序。QOR由这类系统中抽象出的通用功能模块构成,其中包含灵活可配置的后台、内容发布系统、媒体库等等。
文档:
https://doc.getqor.com/
代码:
https://github.com/golangpkg/qor-cms-demos
全部qor文章:
https://blog.csdn.net/freewebsys/article/category/7742598
1,关于富文本
qor-admin系统上面有一个默认的富文本编辑器。
但是特别的简单,有个图片上传的功能,但是不太好使用。
还是老kindeditor好用,看着也舒服多了。
关于这个类型开发还是花了不少的时间研究。
才研究明白,qor的扩展需要按照一些规则开发就行。
https://doc.getqor.com/admin/extend_admin.html#create-new-meta-types
代码:
https://github.com/golangpkg/qor-cms-demos/tree/master/demo07-my-meta-type
2,meta-types类型
再main.go 当中就一个Type类型:
//自定义组件:
product.Meta(&admin.Meta{Name: "Description2", Type: "kindeditor"})
剩下的就是配置和js代码:
再demo07 下面,目录文件夹 app/views/qor/assets/javascripts,放kindeditor 资源文件。
而模板文件在 app/views/qor/metas/form 下面有一个和type 类型定义一样的 kindeditor.tmpl。
模板文件内容:
<div class="qor-field">
<label class="qor-field__label" for="{{.InputId}}">
{{meta_label .Meta}}
</label>
<div class="qor-field__show qor-redactor__show redactor-styles">{{raw .Value}}</div>
<div class="qor-field__edit qor-field__block">
<textarea class="qor-field__input kindeditor-id" id="kindeditor-id" name="{{.InputName}}"
style="width:700px;height:650px;"
data-redactor-settings="{"plugins":["source","filemanager",]}"
data-toggle="qor.kindeditor"
{{if not (has_change_permission .Meta) }}disabled{{end}}>{{.Value}}</textarea>
</div>
</div>
<script src="/admin/assets/javascripts/kindeditor-all-min.js"></script>
<script src="/admin/assets/javascripts/qor_kindeditor.js"></script>
其中不能再模板中写js代码。本来想用id,name 标识下多个kindeditor,然后没有办法了。
用js之后参数,变风就传递不了了。同时,kindeditor 的初始化也研究折腾了半天。
要使用 qor-admin的enable 事件,才可以。这个还是参考rich_editor.tmpl 模板的。
要不然,会遇到一个只能运行一次的bug。kindeditor只能初始化一次。
再修改的时候,界面就不显示kindeditor了。必须用enable 的事件实现才行。
js代码:
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
let componentHandler = window.componentHandler,
NAMESPACE = 'qor.kindeditor',
EVENT_ENABLE = 'enable.' + NAMESPACE,
EVENT_DISABLE = 'disable.' + NAMESPACE,
EVENT_UPDATE = 'update.' + NAMESPACE,
SELECTOR_COMPONENT = '[class*="mdl-js"],[class*="mdl-tooltip"]';
function enable(target) {
//console.log("################### kindeditor enable ###################");
/*jshint undef:false */
var editor = KindEditor.create('#kindeditor-id',{ uploadJson : '/common/kindeditor/upload?dir=image', allowFileManager : false, afterBlur: function(){this.sync();} }); }
function disable(target) { //console.log("################### kindeditor disable ###################"); }
$(function() { $(document) .on(EVENT_ENABLE, function(e) { enable(e.target); }) .on(EVENT_DISABLE, function(e) { disable(e.target); }) .on(EVENT_UPDATE, function(e) { disable(e.target); enable(e.target); }); });
});
//console.log("################### kindeditor load finish ###################");
3,增加上传controller
本来想使用qor-admin内部的写个上传。
但是发现有点费劲,还是使用beego的框架写了一个上传的controller。
同时qor-admin也支持beego框架。
FileUploadController.go 上传代码:
package main
import (
"github.com/astaxie/beego/logs"
"github.com/google/uuid"
"time"
"fmt"
"path/filepath"
"github.com/astaxie/beego"
"os"
)
type FileUploadController struct {
beego.Controller
}
//定义Kindeditor特殊的返回json。
type UploadMessage struct {
Error int64 `json:"error"`
Message string `json:"message"`
Url string `json:"url"`
}
// 判断所给路径文件/文件夹是否存在
func Exists(path string) bool {
_, err := os.Stat(path) //os.Stat获取文件信息
if err != nil {
if os.IsExist(err) {
return true
}
return false
}
return true
}
//https://github.com/google/uuid
//
func (c *FileUploadController) Upload() {
fileNameKey := "imgFile"
uploadDir := beego.AppConfig.String("uploadDir")
uploadBaseUrl := beego.AppConfig.String("uploadBaseUrl")
file, header, err := c.GetFile(fileNameKey) // where <<this>> is the controller and <<file>> the id of your form field
defer c.ServeJSON()
if file != nil {
// get the filename
fileName := header.Filename
fileNameUuid, _ := uuid.NewUUID()
fileNameExt := filepath.Ext(fileName)
t := time.Now()
pathDir := fmt.Sprintf("%d/%d-%02d", t.Year(), t.Year(), t.Month())
if !Exists(uploadDir + pathDir) {
// 创建文件夹
logs.Info("########### no pathDir, make it : %v ", uploadDir+pathDir)
os.MkdirAll(uploadDir+pathDir, os.ModePerm)
}
pathUrl := fmt.Sprintf("%s/%s%s", pathDir, fileNameUuid.String(), fileNameExt)
logs.Info("########### file : %v baseDir : %v pathUrl : %v", fileName, pathDir, pathUrl)
// save to server
err := c.SaveToFile(fileNameKey, uploadDir+pathUrl)
if err != nil {
c.Data["json"] = &UploadMessage{Error: 1, Message: err.Error()}
} else {
logs.Info("########### upload url : %v", uploadBaseUrl+pathUrl)
c.Data["json"] = &UploadMessage{Error: 0, Message: "", Url: uploadBaseUrl + pathUrl}
}
}
logs.Info("########### file %v eror: %v", file, err)
}
上传文件使用uuid进行重命名,然后按照年月,做文件夹,防止一个文件下面文件过多。
使用beego upload 实现。
把上传目录和 上传后的图片地址写到 配置文件中:
appname = qor-cms-demos-07
httpport = 9000
runmode = dev
uploadDir = /go/src/github.com/golangpkg/qor-cms-demos/demo07-my-meta-type/static/img/
uploadBaseUrl = http://127.0.0.1:9000/static/img/
整个main代码:
package main
import (
"fmt"
"net/http"
"github.com/qor/admin"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
//windows需要下载 http://tdm-gcc.tdragon.net/download
"time"
"github.com/astaxie/beego"
"github.com/qor/media/asset_manager"
)
// 用户
type Product struct {
gorm.Model
Name string
Password string
Description string
Description2 string
Year string
ReleaseDate time.Time
}
func main() {
// 注册数据库,可以是sqlite3 也可以是 mysql 换下驱动就可以了。
DB, _ := gorm.Open("sqlite3", "demo.db")
DB.AutoMigrate(&Product{}, &asset_manager.AssetManager{},) //自动创建表。
// 初始化admin 还有其他的,比如API
Admin := admin.New(&admin.AdminConfig{SiteName: "demo", DB: DB})
// 创建admin后台对象资源。
product := Admin.AddResource(&Product{})
//属性配置:https://doc.getqor.com/admin/fields.html
product.Meta(&admin.Meta{Name: "ReleaseDate", Type: "date"})
product.Meta(&admin.Meta{Name: "Password", Type: "password"})
//product.Meta(&admin.Meta{Name: "Description", Type: "rich_editor"})
assetManager := Admin.AddResource(&asset_manager.AssetManager{}, &admin.Config{Invisible: true})
product.Meta(&admin.Meta{Name: "Description", Config: &admin.RichEditorConfig{
AssetManager: assetManager,
Plugins: []admin.RedactorPlugin{
{Name: "medialibrary", Source: "/admin/assets/javascripts/qor_redactor_medialibrary.js"},
{Name: "table", Source: "/admin/assets/javascripts/qor_kindeditor.js"},
},
Settings: map[string]interface{}{
"medialibraryUrl": "/admin/product_images",
},
}})
//https://doc.getqor.com/admin/extend_admin.html#create-new-meta-types
//自定义组件:
product.Meta(&admin.Meta{Name: "Description2", Type: "kindeditor"})
fmt.Println(product)
// 启动服务
mux := http.NewServeMux()
Admin.MountTo("/admin", mux)
fmt.Println("Listening on: 9000")
//http.ListenAndServe(":9000", mux)
beego.Handler("/admin/*", mux)
beego.Router("/common/kindeditor/upload", &FileUploadController{},"post:Upload")
beego.Run()
}
最后使用 beego 配置上传路由。
4,效果图片
上传图片:
上传之后的图片:
而qor的编辑器就功能少了很多:
5,总结
kindeditor增加一个qor-admin的meta类型,折腾好久才明白。
模板当中只能引入js初始化,不能写个js,并且要使用meta的enable事件。
每次再修改编辑的时候都要初始化,显示有问题。然后就是配置上传controller。
使用beego实现,非常方便,接管路由。配置上传controller。
这样就完美多了。
本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/80767649
博主地址是:http://blog.csdn.net/freewebsys